c++17 std::variant

c++17 std::variant

说明

类模板 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) 要求(特别是不允许数组类型和非对象类型)。

代码


#include <variant>
#include <string>
#include <cassert>
#include <iostream>

/*
类模板 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) 要求(特别是不允许数组类型和非对象类型)。
*/

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&) 
    {
    }
    
    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");
    // 传递 char const * 时转换成 void const *
    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";
    }
    // test
    std::variant<int, float, std::string, void const*> test;
    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 = 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;
}

输出

x std::string:def
y std::string:xyz
char*:abc
string:efg
int:1

参考

https://zh.cppreference.com/w/cpp/utility/variant

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值