说明
类模板 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) 要求(特别是不允许数组类型和非对象类型)。
代码
1 2 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; }
|
输出
1 2 3 4 5
| x std::string:def y std::string:xyz char*:abc string:efg int:1
|
参考
https://zh.cppreference.com/w/cpp/utility/variant