std::variant
std::variant
C++17增加std::variant实现类似union的功能,但却比union更高级,variant主要是为了提供更安全的union。举个例子union里面不能有string这种类型,但std::variant却可以,还可以支持更多复杂类型,如map等。
std::variant<> 常用操作
操作 | 说明 |
---|---|
index() | 返回当前备选项的索引 |
get |
返回备选项类型为T的值或抛出异常(如果没有类型为T的值) |
get |
返回备选项索引为idx的值或抛出异常(如果没有索引为idx的值)分配一个新值 |
get_if |
返回指向类型为T指针或返回nullptr(如果没有类型为T的值) |
get_if |
返回指向索引Idx的指针或nullpt(如果没有索引为idx的值) |
#include <bits/stdc++.h>
using namespace std;
struct A {
A(int i) {
a = i;
}
int a;
};
int main() {
std::variant<double, std::string, int> var1("hahaha"), var2;
cout << "var1.index:"<< var1.index() << endl;
var1 = 123;
cout << "var1.index:"<< var1.index() << endl;
var2 = 123.32;
cout << "var2.index:" << var2.index() << endl;
try {
var1 = "xixixi";
std::string str = std::get<std::string>(var1); // 通过类型获取值
var1 = 3;
int i = std::get<2>(var1); // 通过index获取对应值
cout << str << endl;
cout << i << endl;
} catch (const std::bad_variant_access& e) {
}
//variant的第一个类型一般要有对应的构造函数,否则编译失败
//可以使用std::monostate来打个桩,模拟一个空状态
// std::variant<A, double> var3; // 编译失败,因为没有无参构造函数
// std::variant<A, double> var3{A{2}}; // 编译成功
std::variant<std::monostate, A> var3; // 可以编译成功
var3 = A{3};
cout << "var3.index:"<< var3.index() << endl;
auto a = std::get<A>(var3); // 通过类型获取值
cout << "a.a:" << a.a << endl;
return 0;
}