std::variant<Types...>::variant
来自cppreference.com
                    
                                        
                    
                    
                                                            
                    | constexpr variant() noexcept(/* see below */); | (1) | (C++17 起) | 
| constexpr variant( const variant& other ); | (2) | (C++17 起) | 
| constexpr variant( variant&& other ) noexcept(/* see below */); | (3) | (C++17 起) | 
| template< class T > constexpr variant( T&& t ) noexcept(/* see below */); | (4) | (C++17 起) | 
| template< class T, class... Args > constexpr explicit variant( std::in_place_type_t<T>, Args&&... args ); | (5) | (C++17 起) | 
| template< class T, class U, class... Args > constexpr explicit variant( std::in_place_type_t<T>, | (6) | (C++17 起) | 
| template< std::size_t I, class... Args > constexpr explicit variant( std::in_place_index_t<I>, Args&&... args ); | (7) | (C++17 起) | 
| template< std::size_t I, class U, class... Args > constexpr explicit variant( std::in_place_index_t<I>, | (8) | (C++17 起) | 
构造新的 variant 对象。
1) 默认构造函数。构造 
variant ,保有首个可选项的值初始化的值( index() 为零)。
-  当且仅当可选项类型 T_0的值初始化满足 constexpr 函数的要求,此构造函数才为constexpr。
-  此重载仅若 std::is_default_constructible_v<T_0> 为 true才参与重载决议。
2) 复制构造函数。若 
other 非因异常无值,则构造一个保有与 other 相同可选项的 variant ,并以 std::get<other.index()>(other) 直接初始化所含值。否则,初始化一个因异常无值的 variant 。
-  此构造函数定义为被删除,除非 std::is_copy_constructible_v<T_i> 对于所有 Types...中的T_i为true。
-  若 std::is_trivially_copy_constructible_v<T_i> 对 Types...中的所有T_i为 true 则它为平凡。
3) 移动构造函数。若 
other 非因异常无值,则构造一个保有与 other 相同可选项的 variant 并以 std::get<other.index()>(std::move(other)) 直接初始化所含值。否则,初始化一个因异常无值的 variant。
-  此重载仅若 std::is_move_constructible_v<T_i> 对于所有Types...中的T_i为true才参与重载决议。
-  若 std::is_trivially_move_constructible_v<T_i> 对 Types...中的所有T_i为 true 则它为平凡。
4) 转换构造函数。构造保有会被重载决议对表达式 F(std::forward<T>(t)) 选择的可选项 
T_j ,假设对来自 Types... 中的每个 T_i 同时存在一个虚构函数 F(T_i) 的重载,除了:
-  仅若声明 T_i x[] = { std::forward<T>(t) }; 对某个虚设变量 x才考虑 F(T_i) ;
-  若 T_i是(可有 cv 限定的) bool ,则仅若 std::decay_t<T> (C++20 前)std::remove_cvref_t<T> (C++20 起) 亦为 bool 才考虑 F(T_i) 。
 
-  仅若声明 T_i x[] = { std::forward<T>(t) }; 对某个虚设变量 
 如同用直接非列表初始化从 std::forward<T>(t) 直接初始化所含值。
-  此重载仅若
- sizeof...(Types) > 0 ,
- std::decay_t<U> (C++20 前)std::remove_cvref_t<U> (C++20 起) 既不与 variant 为同一类型,亦非 std::in_place_type_t 或 std::in_place_index_t 的特化,
-   std::is_constructible_v<T_j, T> 为 true,
-  且表达式 F(std::forward<T>(t)) (令 F为上述虚构函数的重载集)为良构才参与重载决议。
 
-  若 T_j的被选择构造函数为 constexpr 构造函数,则此构造函数为 constexpr 构造函数。
std::variant<std::string> v("abc"); // OK std::variant<std::string, std::string> w("abc"); // 谬构 std::variant<std::string, const char*> x("abc"); // OK :选择 const char* std::variant<std::string, bool> y("abc"); // OK :选择 string ; bool 不是候选 std::variant<float, long, double> z = 0; // OK :保有 long // float 与 double 不是候选
5) 构造一个有指定可选项类型 
T 的 variant 并以参数 std::forward<Args>(args)... 初始化所含值。
-  若 T的被选择构造函数是 constexpr 构造函数,则此构造函数亦为 constexpr 构造函数。
-  此重载仅若 Types...中正好出现一次T且 std::is_constructible_v<T, Args...> 为true才参与重载决议。
6) 构造一个有指定可选项类型 
T 的 variant 并以参数 il, std::forward<Args>(args)... 初始化所含值。
-  若 T的被选择构造函数是 constexpr 构造函数,则此构造函数亦为 constexpr 构造函数。
-  此重载仅若 Types...中正好出现一次T且 std::is_constructible_v<T, initializer_list<U>&, Args...> 为true才参与重载决议。
7) 构造一个有下标 
I 所指定的可选项类型 {{tt|T_i} }的 variant 并以参数std::forward<Args>(args)... 初始化所含值。
-  若 T_i的被选择构造函数是 constexpr 构造函数,则此构造函数亦为 constexpr 构造函数。
-  此重载仅若 I < sizeof...(Types) 与 std::is_constructible_v<T_i, Args...> 皆为 true才参与重载决议。
8) 构造一个有下标 
I 所指定的可选项类型 T_i 的 variant 并以参数 il, std::forward<Args>(args)... 初始化所含值。
-  若 T_i的被选择构造函数是 constexpr 构造函数,则此构造函数亦为 constexpr 构造函数。
-  此重载仅若 I < sizeof...(Types) 与 std::is_constructible_v<T_i, std::initializer_list<U>&, Args...> 皆为 true才参与重载决议。
参数
| other | - | 另一个要复制/移动其所含值的 variant对象 | 
| t | - | 用以初始化被所含值的值 | 
| args... | - | 用以初始化被所含值的参数 | 
| il | - | 用以初始化被所含值的初始化器列表 | 
| a | - | 传递给被所含值的分配器 | 
异常
1) 可能抛出首个可选项的值初始化所抛的任何异常。 
noexcept 规定:  
noexcept(std::is_nothrow_default_constructible_v<T_0>)
2) 可能抛出直接初始化任何 
Types... 中的 T_i 所抛的任何异常。3) 可能抛出移动构造任何 
Types... 中的 T_i 所抛的任何异常。 noexcept 规定:  
noexcept( (std::is_nothrow_move_constructible_v<Types> && ...))
5-8) 可能抛出调用所选可选项的所选构造函数所抛的任何异常。
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| DR | 应用于 | 出版时的行为 | 正确行为 | 
|---|---|---|---|
| LWG 2901 | C++17 | 提供具分配器构造函数但 variant不能正确支持分配器 | 移除构造函数 | 
| P0739R0 | C++17 | 转换构造函数模板与类模板实参推导交互困难 | 添加了制约 | 
| LWG 3024 | C++17 | 若任何成员类型非可复制,则复制构造函数不参与重载决议 | 改为定义为被删除 | 
| P0602R4 | C++17 | 即使底层构造函数平凡,复制/移动构造函数亦可为非平凡 | 要求传播平凡性 | 
| P0608R3 | C++17 | 转换构造函数盲目地组成重载集,导致不想要的转换 | 不考虑窄化与布尔转换 | 
示例
| 本节未完成 原因:暂无示例 | 
 
	