# 标准库头文件 <variant>

< cpp‎ | header

此头文件是通用工具库的一部分。

### 包含
<compare> (C++20) | 三路比较运算符支持
### 类
variant (C++17) | 类型安全的可辨识联合体 (类模板)
monostate (C++17) | 用作非可默认构造类型的 `variant` 的首个可选项的占位符类型 (类)
bad_variant_access (C++17) | 非法地访问 `variant` 的值时抛出的异常 (类)
variant_size variant_size_v (C++17) | 在编译时获得 `variant` 可选项列表的大小 (类模板) (变量模板)
variant_alternative variant_alternative_t (C++17) | 在编译时获得以其下标指定的可选项的类型 (类模板) (别名模板)
std::hash<std::variant> (C++17) | 特化 std::hash 算法 (类模板特化)
### 常量
variant_npos (C++17) | 非法状态的 `variant` 的下标 (常量)
### 函数
visit (C++17) | 以一或多个 `variant` 所保有的各实参调用所提供的函数对象 (函数模板)
holds_alternative (C++17) | 检查某个 `variant` 是否当前持有某个给定类型 (函数模板)
std::get(std::variant) (C++17) | 以给定索引或类型（若类型唯一）读取 `variant` 的值，错误时抛出异常 (函数模板)
get_if (C++17) | 以给定索引或类型（若其唯一），获得指向被指向的 variant 的值的指针，错误时返回空指针 (函数模板)
operator==operator!=operator<operator<=operator>operator>=operator<=> (C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20) | 以所含值比较 `variant` 对象 (函数模板)
std::swap(std::variant) (C++17) | 特化 std::swap 算法 (函数模板)

### 概要

    #include <compare>

    namespace std {
      // 类模板 variant
      template<class... Types>
        class variant;

      // variant helper classes
      template<class T> struct variant_size;                        // 不定义
      template<class T> struct variant_size<const T>;
      template<class T>
        inline constexpr size_t variant_size_v = variant_size<T>::value;

      template<class... Types>
        struct variant_size<variant<Types...>>;

      template<size_t I, class T> struct variant_alternative;       // 不定义
      template<size_t I, class T> struct variant_alternative<I, const T>;
      template<size_t I, class T>
        using variant_alternative_t = typename variant_alternative<I, T>::type;

      template<size_t I, class... Types>
        struct variant_alternative<I, variant<Types...>>;

      inline constexpr size_t variant_npos = -1;

      // 值访问
      template<class T, class... Types>
        constexpr bool holds_alternative(const variant<Types...>&) noexcept;

      template<size_t I, class... Types>
        constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&);
      template<size_t I, class... Types>
        constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&);
      template<size_t I, class... Types>
        constexpr const variant_alternative_t<I, variant<Types...>>&
          get(const variant<Types...>&);
      template<size_t I, class... Types>
        constexpr const variant_alternative_t<I, variant<Types...>>&&
          get(const variant<Types...>&&);

      template<class T, class... Types>
        constexpr T& get(variant<Types...>&);
      template<class T, class... Types>
        constexpr T&& get(variant<Types...>&&);
      template<class T, class... Types>
        constexpr const T& get(const variant<Types...>&);
      template<class T, class... Types>
        constexpr const T&& get(const variant<Types...>&&);

      template<size_t I, class... Types>
        constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
          get_if(variant<Types...>*) noexcept;
      template<size_t I, class... Types>
        constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
          get_if(const variant<Types...>*) noexcept;

      template<class T, class... Types>
        constexpr add_pointer_t<T>
          get_if(variant<Types...>*) noexcept;
      template<class T, class... Types>
        constexpr add_pointer_t<const T>
          get_if(const variant<Types...>*) noexcept;

      // 关系运算符
      template<class... Types>
        constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
      template<class... Types>
        constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
      template<class... Types>
        constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
      template<class... Types>
        constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
      template<class... Types>
        constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
      template<class... Types>
        constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
      template<class... Types> requires (three_way_comparable<Types> && ...)
        constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
          operator<=>(const variant<Types...>&, const variant<Types...>&);

      // 观览
      template<class Visitor, class... Variants>
        constexpr /* 见描述 */ visit(Visitor&&, Variants&&...);
      template<class R, class Visitor, class... Variants>
        constexpr R visit(Visitor&&, Variants&&...);

      // 类 monostate
      struct monostate;

      // monostate 关系运算符
      constexpr bool operator==(monostate, monostate) noexcept;
      constexpr strong_ordering operator<=>(monostate, monostate) noexcept;

      // 特化的算法
      template<class... Types>
        constexpr void swap(variant<Types...>&,
                            variant<Types...>&) noexcept(/* 见描述 */);

      // 类 bad_variant_access
      class bad_variant_access;

      // 散列支持
      template<class T> struct hash;
      template<class... Types> struct hash<variant<Types...>>;
      template<> struct hash<monostate>;
    }

    // 弃用
    namespace std {
      template<class T> struct variant_size<volatile T>;
      template<class T> struct variant_size<const volatile T>;

      template<size_t I, class T> struct variant_alternative<I, volatile T>;
      template<size_t I, class T> struct variant_alternative<I, const volatile T>;
    }

#### 类模板 std::variant

    namespace std {
      template<class... Types>
      class variant {
      public:
        // 构造函数
        constexpr variant() noexcept(/* 见描述 */);
        constexpr variant(const variant&);
        constexpr variant(variant&&) noexcept(/* 见描述 */);

        template<class T>
          constexpr variant(T&&) noexcept(/* 见描述 */);

        template<class T, class... Args>
          constexpr explicit variant(in_place_type_t<T>, Args&&...);
        template<class T, class U, class... Args>
          constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...);

        template<size_t I, class... Args>
          constexpr explicit variant(in_place_index_t<I>, Args&&...);
        template<size_t I, class U, class... Args>
          constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);

        // 析构函数
        constexpr ~variant();

        // 赋值
        constexpr variant& operator=(const variant&);
        constexpr variant& operator=(variant&&) noexcept(/* 见描述 */);

        template<class T> constexpr variant& operator=(T&&) noexcept(/* 见描述 */);

        // 修改器
        template<class T, class... Args>
          constexpr T& emplace(Args&&...);
        template<class T, class U, class... Args>
          constexpr T& emplace(initializer_list<U>, Args&&...);
        template<size_t I, class... Args>
          constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
        template<size_t I, class U, class... Args>
          constexpr variant_alternative_t<I, variant<Types...>>&
            emplace(initializer_list<U>, Args&&...);

        // 值状态
        constexpr bool valueless_by_exception() const noexcept;
        constexpr size_t index() const noexcept;

        // 交换
        constexpr void swap(variant&) noexcept(/* 见描述 */);
      };
    }

#### 类 std::monostate

    struct monostate{};

#### 类 std::bad_variant_access

    class bad_variant_access : public exception {
    public:
      // 特殊成员函数的规范见 [exception]
      const char* what() const noexcept override;
    };