C++ 参考手册
- C++11
- C++14
- C++17
- C++20
- C++ 编译器支持情况表
- 独立与宿主实现
- C++ 语言
- C++ 关键词
- 预处理器
- C++ 标准库头文件
- 具名要求
- 功能特性测试 (C++20)
- 工具库
- 程序支持工具
- std::initializer_list
- 函数对象
- std::hash
- std::pair
- std::tuple
- std::optional
- std::any
- std::variant
- std::hash <std::variant>
- std::variant<Types...>::operator=
- std::variant<Types...>::variant
- std::variant<Types...>::~variant
- std::variant<Types...>::index
- std::variant<Types...>::valueless_by_exception
- std::variant<Types...>::emplace
- std::variant<Types...>::swap
- std::visit
- std::holds_alternative
- std::get (std::variant)
- std::get_if
- operator==, !=, <, <=, >, >=, <=>(std::variant)
- std::swap(std::variant)
- std::monostate
- std::bad_variant_access
- std::variant_size, std::variant_size_v
- std::variant_alternative, std::variant_alternative_t
- std::variant_npos
- std::apply
- 库特性测试宏 (C++20)
- 格式化库 (C++20)
- std::integer_sequence
- std::exchange
- std::make_from_tuple
- std::launder
- std::to_chars
- std::from_chars
- std::as_const
- std::source_location
- 变参数函数
- std::bitset
- std::cmp_equal, cmp_not_equal, cmp_less, cmp_greater, cmp_less_equal, cmp_greater_equal
- std::in_range
- std::declval
- std::forward
- std::move
- std::move_if_noexcept
- std::chars_format
- std::piecewise_construct_t
- std::piecewise_construct
- std::in_place, std::in_place_type, std::in_place_index, std::in_place_t, std::in_place_type_t, std::in_place_index_t
- 注释
- 类型支持(基本类型、RTTI、类型特性)
- 概念库 (C++20)
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 容器库
- 迭代器库
- 范围库 (C++20)
- 算法库
- 数值库
- 输入/输出库
- 文件系统库
- 本地化库
- 正则表达式库
- 原子操作库
- 线程支持库
- 实验性 C++ 特性
- 有用的资源
- 索引
- std 符号索引
- 协程支持 (C++20)
- C++ 关键词
位置:首页 > C++ 参考手册 >工具库 >std::variant > std::variant<Types...>::variant
std::variant<Types...>::variant
constexpr variant() noexcept(/* see below */); |
(1) | (C++17 起) |
variant(const variant& other); |
(2) | (C++17 起) |
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
。3) 移动构造函数。若
other
非因异常无值,则构造一个保有与 other
相同可选项的 variant
并以 std::get<other.index()>(std::move(other)) 直接初始化所含值。否则,初始化一个因异常无值的 variant
。此重载仅若 std::is_move_constructible_v<T_i> 对于所有Types...
中的 T_i
为 true
才参与重载决议。4) 转换构造函数。构造一个保有可选项类型
T_j
的 variant
, T_j
将是表达式 F(std::forward<T>(t)) 的重载决议所选的类型,假设对每个来自 Types...
的 T_i
在作用域中同时存在一个虚构函数 F(T_i)
的重载决议。直接初始化所含值,如同通过从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 构造函数。
variant<string> v("abc"); // OK variant<string, string> w("abc"); // 病式,无法选择要转换到的可选项 variant<string, bool> x("abc"); // OK ,但选择 bool
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 | 转换构造函数盲目地组成重载集,导致不想要的转换 | 不考虑窄化与布尔转换 |
示例
本节未完成 原因:暂无示例 |