std::variant

来自cppreference.com
< cpp‎ | utility
 
 
 
 
定义于头文件 <variant>
template <class... Types>
class variant;
(C++17 起)

类模板 std::variant 表示一个类型安全的联合体std::variant 的一个实例在任意时刻要么保有其一个可选类型之一的值,要么在错误情况下无值(此状态难以达成,见 valueless_by_exception )。

与联合体在聚合初始化中的行为一致, 若 variant 保有某个对象类型 T 的值,则直接于 variant 的对象表示中分配 T 的对象表示。不允许 variant 分配额外的(动态)内存。

variant 不容许保有引用、数组,或类型 void 。空 variant 亦为病式(可用 std::variant<std::monostate> 代替)。

variant 容许保有同一类型多于一次,而且可保有同一类型的不同 cv 限定版本。

同联合体,默认构造的 variant 保有其首个选项的值,除非该选项不是可默认构造的(该情况下 variant 亦非可默认构造:能用辅助类 std::monostate 使这种 variant 可默认构造)。

目录

[编辑] 模板形参

Types - 可存储于此 variant 中的类型。所有类型必须是(可有 cv 限定的)非数组对象类型。

[编辑] 成员函数

构造 variant 对象
(公开成员函数) [编辑]
析构 variant 同其所含的值
(公开成员函数) [编辑]
赋值 variant
(公开成员函数) [编辑]
观察器
返回 variant 所保有可选项的零基下标
(公开成员函数) [编辑]
检查 variant 是否在非法状态
(公开成员函数) [编辑]
修改器
原位构造 variant 中的值
(公开成员函数) [编辑]
与另一 variant 交换
(公开成员函数) [编辑]

[编辑] 非成员函数

(C++17)
以一或多个 variant 所保有的参数的调用提供的函数对象
(函数模板) [编辑]
检查给定类型在 variant 中是否准确出现一次
(函数模板) [编辑]
读取 variant 给定下标或类型的值(若类型唯一),错误时抛出异常
(函数模板) [编辑]
(C++17)
给定下标或类型(若类型唯一),获得指向被指向的 variant 的值的指针,错误时返回空指针
(函数模板) [编辑]
以所含值比较 variant 对象
(函数模板) [编辑]
特化 std::swap 算法
(函数) [编辑]

[编辑] 辅助类

(C++17)
用作非可默认构造类型的 variant 的首个可选项的占位符类型
(类) [编辑]
非法地访问 variant 的值时抛出的异常
(类) [编辑]
在编译时获得 variant 可选项列表的大小
(类模板) (变量模板) [编辑]
在编译时获得以其下标指定的可选项的类型
(类模板) (别名模板) [编辑]
特化 std::hash 算法
(类模板特化) [编辑]

[编辑] 辅助对象

非法状态的variant的下标
(常量) [编辑]

[编辑] 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 2901 C++17 提供 std::uses_allocator 的特化,但 variant 不能正确支持分配器 移除特化

[编辑] 示例

#include <variant>
#include <string>
#include <cassert>
 
using namespace std::literals;
 
int main()
{
    std::variant<int, float> v, w;
    v = 12; // v 含有 int
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // 与前一行效果相同
    w = v; // 与前一行效果相同
 
//  std::get<double>(v); // 错误: [int, float] 中无 double
//  std::get<3>(v);      // 错误:合法下标值是 0 与 1
 
    try {
      std::get<float>(w); // w 含 int ,非 float :将抛出
    }
    catch (const std::bad_variant_access&) {}
 
    std::variant<std::string> x("abc"); // 无歧义时的转换构造函数
    x = "def"; // 无歧义时的转换赋值
 
    std::variant<std::string, bool> y("abc"); // 传递 char const * 时转换成 *bool*
    assert(std::holds_alternative<bool>(y)); // 成功
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); // 成功
}


[编辑] 参阅

原位构造标签
(类模板) [编辑]
(C++17 起)
可能或可能不保有一个对象的包裹器
(类模板) [编辑]
(C++17 起)
保有任何可复制构造 (CopyConstructible) 类型实例的对象。
(类) [编辑]