说明
类模板 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 中的类型。所有类型必须满足可析构 (Destructible) 要求(特别是不允许数组类型和非对象类型)。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 
 | #include <variant>
 #include <string>
 #include <cassert>
 #include <iostream>
 
 
 
 
 
 
 
 
 
 
 
 int main()
 {
 std::variant<int, float> v, w;
 v = 12;
 int i = std::get<int>(v);
 w = std::get<int>(v);
 w = std::get<0>(v);
 w = v;
 
 
 try {
 std::get<float>(w);
 }
 catch (const std::bad_variant_access&)
 {
 }
 
 using namespace std::literals;
 
 std::variant<std::string> x("abc");
 x = "def";
 if (std::holds_alternative<std::string>(x))
 {
 std::cout << "x std::string:" << std::get<std::string>(x) << "\n";
 }
 std::variant<std::string, void const*> y("abc");
 
 y = "xyz"s;
 if (std::holds_alternative<std::string>(y))
 {
 std::cout << "y std::string:" << std::get<std::string>(y) << "\n";
 }
 if (std::holds_alternative<void const*>(y))
 {
 std::cout << "y char const *:" << (char const *)std::get<void const*>(y) << "\n";
 }
 
 std::variant<int, float, std::string, void const*> test;
 test = 1;
 test = "abc";
 
 if (std::holds_alternative<std::string>(test))
 {
 std::cout << "string:" << std::get<std::string>(test) << "\n";
 }
 if (std::holds_alternative<int>(test))
 {
 std::cout << "int:" << std::get<int>(test) << "\n";
 }
 if (std::holds_alternative<void const*>(test))
 {
 std::cout << "char*:" << (char const*)std::get<void const*>(test) << "\n";
 }
 test = 1;
 test = "abc";
 test = std::string("efg");
 if (std::holds_alternative<std::string>(test))
 {
 std::cout << "string:" << std::get<std::string>(test) << "\n";
 }
 if (std::holds_alternative<int>(test))
 {
 std::cout << "int:" << std::get<int>(test) << "\n";
 }
 if (std::holds_alternative<void const*>(test))
 {
 std::cout << "char*:" << (char const*)std::get<void const*>(test) << "\n";
 }
 test = std::string("efg");
 test = "abc";
 test = 1;
 if (std::holds_alternative<std::string>(test))
 {
 std::cout << "string:" << std::get<std::string>(test) << "\n";
 }
 if (std::holds_alternative<int>(test))
 {
 std::cout << "int:" << std::get<int>(test) << "\n";
 }
 if (std::holds_alternative<void const*>(test))
 {
 std::cout << "char*:" << std::get<void const*>(test) << "\n";
 }
 return 0;
 }
 
 
 | 
输出
| 12
 3
 4
 5
 
 | x std::string:defy std::string:xyz
 char*:abc
 string:efg
 int:1
 
 | 
参考
https://zh.cppreference.com/w/cpp/utility/variant