c++ 17 std::variant

C++17增加std::variant实现类似union的功能,但却比union更高级,举个例子union里面不能有string这种类型,但std::variant却可以,还可以支持更多复杂类型,如map等。

注意,不允许使用空变量、具有引用成员的变量、具有c样式数组成员的变量和具有不完整类型(如void)的变量。没有空的状态:这意味着对于每个构建的对象,必须至少调用一个构造函数。默认构造函数初始化第一个类型(通过第一个类型的默认构造函数):

1.默认情况下,变量的默认构造函数调用第一个备选项的默认构造函数:

2.成员函数index()可用于查明当前设置了哪个选项(第一个选项的索引为0)。

3.访问值的通常方法是调用get<>()获取对应的选项值。可以传递它的索引或者类型

#include
 
std::variant var{"hi"}; // initialized with string alternative
std::cout << var.index(); // prints 1
var = 42; // now holds int alternative
std::cout << var.index(); // prints 0

var = "world";
...
try {
std::string s = std::get(var); // access by type   

std::cout << s << std::endl;   //world

var = 3;
int i = std::get<0>(var); // access by index    

std::cout << i << std::endl;   //3
}
catch (const std::bad_variant_access& e) { // in case a wrong type/index is used

如果没有为第一个类型定义默认构造函数,则调用该变量的默认构造函数会在编译时错误:
#include
#include
 
struct NoDefConstr
{
    NoDefConstr(int i)
    {
        std::cout << "NoDefConstr::NoDefConstr(int) called\n";
    }
};
 
int main()
{
    std::variant v1; // ERROR: can’t default construct first type
 
    return 0;

不过辅助类型std::monostate提供了处理这种情况的能力,还提供了模拟空状态的能力。

std::monostate
为了支持第一个类型没有默认构造函数的variant对象,提供了一个特殊的helper类型:std::monostate。类型std::monostate的对象总是具有相同的状态,因此,它们总是相等的。它自己的目的是表示另一种类型,这样variant就没有任何其他类型的值。也就是说,std::monostate可以作为第一种替代类型,使变体类型默认为可构造。

std::variant v2; // OK
std::cout << "index: " << v2.index() << '\n'; // prints 0

4.赋值和emplace()操作对应于初始化:

std::variant var; // sets first int to 0, index()==0
var = "hello"; // sets string, index()==2
var.emplace<1>(42); // sets second int, index()==1

你可能感兴趣的:(c++,c++)