首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

std::variant反射。如何判断分配了哪种类型的值std::variant?

std::variant是C++17中引入的一种数据类型,它可以存储多个不同类型的值,类似于联合体(union),但提供了更安全和方便的使用方式。在使用std::variant时,我们可能需要判断当前存储的是哪种类型的值,可以通过以下几种方法来实现。

  1. 使用std::holds_alternative函数:std::holds_alternative函数可以判断std::variant是否存储了指定类型的值。它接受一个类型作为参数,并返回一个bool值,表示std::variant是否存储了该类型的值。例如,判断std::variant<int, double, std::string>是否存储了int类型的值可以使用以下代码:
代码语言:txt
复制
std::variant<int, double, std::string> var = 42;
if (std::holds_alternative<int>(var)) {
    // var存储了int类型的值
} else if (std::holds_alternative<double>(var)) {
    // var存储了double类型的值
} else if (std::holds_alternative<std::string>(var)) {
    // var存储了std::string类型的值
}
  1. 使用std::get_if函数:std::get_if函数可以获取std::variant存储的指定类型的值的指针。如果std::variant存储的是该类型的值,则返回指向该值的指针;否则返回nullptr。通过判断返回的指针是否为nullptr,我们可以确定std::variant存储的是哪种类型的值。例如,判断std::variant<int, double, std::string>是否存储了int类型的值可以使用以下代码:
代码语言:txt
复制
std::variant<int, double, std::string> var = 42;
if (auto ptr = std::get_if<int>(&var)) {
    // var存储了int类型的值,ptr指向该值
} else if (auto ptr = std::get_if<double>(&var)) {
    // var存储了double类型的值,ptr指向该值
} else if (auto ptr = std::get_if<std::string>(&var)) {
    // var存储了std::string类型的值,ptr指向该值
}
  1. 使用std::visit函数:std::visit函数可以根据std::variant存储的值的类型,调用对应的处理函数。我们可以定义一个visitor对象,其中包含了各种类型值的处理函数,然后使用std::visit函数将visitor对象应用于std::variant。通过在visitor对象的处理函数中判断当前处理的是哪种类型的值,我们可以确定std::variant存储的是哪种类型的值。例如,判断std::variant<int, double, std::string>是否存储了int类型的值可以使用以下代码:
代码语言:txt
复制
std::variant<int, double, std::string> var = 42;
struct Visitor {
    void operator()(int value) {
        // var存储了int类型的值,value为该值
    }
    void operator()(double value) {
        // var存储了double类型的值,value为该值
    }
    void operator()(const std::string& value) {
        // var存储了std::string类型的值,value为该值
    }
};
std::visit(Visitor{}, var);

需要注意的是,以上方法都是在已知std::variant的可能类型的情况下进行判断。如果不知道std::variant的可能类型,可以使用std::holds_alternative和std::get_if结合使用,或者使用std::visit结合使用std::type_index来进行判断。

关于std::variant的更多信息,你可以参考腾讯云C++ SDK中std::variant的相关文档:std::variant文档

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

如何优雅使用 std::variantstd::optional

optional和variant都是和类型(sum type, 表达个数是所有type总和), 区别于struct所表达类型....s = std::get(y); 当然, 如果std::variant中当前存储不是对应Type, 则会抛出std::bad_variant_access类型异常: try {...它还有一个特殊类型 std::nullopt_t, 这个类型std::nullptr_t一样, 只有一个, std::nullopt, optional在没有设置情况下类型就是std::nulopt_t..., std::nullopt. 2.1 has_value() 我们可以通过has_value()来判断对应optional是否处于已经设置状态, 代码如下所示: int main() {...对比简单get方式来说, std::visit相对来说能够更好适配各个使用场合(比如ponder[一个开源C++反射库]中作为统一类型ponder::Value对象就提供了不同种类vistor

2.9K10

多态实现-虚函数、函数指针以及变体

,并不知道b所指对象具体类型,但是有两点很清楚: 无论ptr对应哪种对象,我们总是可以通过ptr找到对应对象vtbl 无论ptr对应哪种对象,Print()函数地址总是在虚函数表第1位 所以,编译器对上述调用将优化成如下...std::variant std::variant是C++17引入变体类型,它最大优势是提供了一种新具有多态性处理不同类型集合方法。...我们可以将其理解为union升级版,之所以称之为升级版,是因为union有如下缺点: 对象并不知道它们现在持有的类型 不能持有std::string等非平凡类型 不能被继承 既然称之为union升级版...,那么union缺点其肯定不存在,在此我们整理了下variant特点: 可以获取当前类型 可以持有任何类型(不能是引用、C类型数组指针、void等) 可以被继承 我们定义了一个如下类型变量v...对于std::variant,其是语义,这就避免了虚函数机制所需要堆上分配,进而提高系统性能。但是其预先需要了解所有可能类型,在扩展方面不是很友好,而虚函数机制则没有此类问题。

88620

心心念念优化完成了,虽然不是很完美

方案一: typelist 既然需求是根据字符串类型来创建对应数据类型,那么不妨把各种数据类型结合起来,而支持多种数据类型,对于这种多类型,第一时间想到了std::variantstd::tuple...,不过因为std::variant使用上限制以及实现本功能的话需要增加很多判断代码,所以最终选择了std::tuple来实现: using types = std::tuple>>(name); } } 在上述中,依然采取配置文件方式,创建了一个支持int、string等类型std...::tuple,并通过getIdx和strings_equal来获取该类型在tuple中index,进而创建相应类型。...这块也在群里进行了讨论,也聊了java中反射实现机制和其弊端。其间,吴老师也发表了相关意见,原来对于反射这块,于13年就专门成立了反射研究组,只是一直没达到能进标准共识。具体可以参考静态反射

14840

C++17 在业务代码中最好用十个特性

,在转换回具体类型时程序无法判断当前void*类型是否真的是 T,容易带来安全隐患。...std::any应当很少是程序员第一选择,在已知类型情况下,std::optional, std::variant和继承都是比它更高效、更合理选择。...常用于可能失败函数返回中,比如工厂函数。在 C++17 之前,往往使用T*作为返回,如果为nullptr则代表函数失败,否则T*指向了真正返回。...>代表一个多类型容器,容器中是制定类型一种,是通用 Sum Type,对应 Rust enum。是一种类型安全union,所以也叫做tagged union。...类型安全,variant 存储了内部类型信息,所以可以进行安全类型转换,c++17 之前往往通过union+enum来实现相同功能。

2.4K20

现代C++教程:高速上手(四)-容器

在插入元素时,会根据<操作符比较元素大小并判断元素是否相同,并选择合适位置插入到容器中。当对这个容器中元素进行遍历时,输出结果会按照<操作符顺序来逐个遍历。...,除了std::pair外,似乎没有现成结构能够用来存放不同类型数据。...元组基本操作 三个核心函数: 1、std::make_tuple: 构造元组 2、std::get:获得元组某个位置 3、std::tie:元组拆包 #include #...: int index = 1; std::get(t); //非法 c++17引入了std::variant,提供给variant类型模版参数 可以让一个variant从而容纳提供几种类型变量...(在其他语言,例如Python/JavaScrpit等,表现为动态类型): #include template <size_t n, typename...

83420

c++17好用新特性总结

void*时,T类型信息就已经丢失了,在转换回具体类型时程序无法判断当前void*类型是否真的是T,容易带来安全隐患。...std::any应当很少是程序员第一选择,在已知类型情况下,std::optional, std::variant和继承都是比它更高效、更合理选择。...return ret; } std::variant std::variant代表一个多类型容器,容器中是制定类型一种,是通用Sum Type,对应Rustenum。...类型安全,variant存储了内部类型信息,所以可以进行安全类型转换,c++17之前往往通过union+enum来实现相同功能。...bool 表达式不能用 ++, – 这两个自增(减)运算符了 c++17中异常已经成为了类型系统一部, 枚举直接列表初始化 结构化绑定 constexpr if 表达式

2.9K10

C++17,标准库有哪些新变化?

,标准模板库中新添加并行算法,新文件系统库,以及3个新数据类型:std::any, std::optional, 和 std::variant.让我们来了解一下其中细节....(译注: 单子(Monad) 是函数式编程编程概念,简单理解的话可以看看这里) 我们再来看下 std::variant. std::variant std::variant 是一个类型安全联合体(union...).一个 std::variant 实例存储着其指定类型中某一类型数据,并且 std::variant 指定类型不能是引用类型,数组类型以及 void 类型,不过 std::variant 可以指定重复数据类型...::variants 实例 v 和 w,他们指定类型为 int 和 float,并且初始为0(第一个指定类型 int 默认初始).第7行代码中我将整型12赋值给了v,后面我们可以通过 std::...get(v) 来获取该.第9行到11行代码中,我使用了3种方式将v中数值赋值给了w. std::variants 使用自然也有一定规则限制,你可以使用指定某一类型(第9行代码)或者指定某一索引(

1.2K10

C++17,optional, any, 和 variant 更多细节

,这是第六篇~ std::optional, std::any, 和 std::variant 有一个共同特点:他们都支持就地构造.另外,std::variant 还支持访问者模式....首先,我们要了解一下这3种数据类型功能作用. std::optional 是一种可能包含也可能不包含某一类型对象类型. std::variant 是一种类型安全联合体 std::any 是一种可以包含任意类型...::variants 列表(代码第11行).每个 variant 都可以包含以下任一类型:char, long, float, int, double, long long.遍历 variant 列表并对每一个...variant 应用 lambda 函数非常简单(代码第15行到17行).借助 typeid 函数,我便可以获得 variant 实际类型(代码第22行到24行).到这里,我想你应该已经看出了代码中访问者模式...现在,我想将各个 variant 元素求和.求和之前,我需要在编译期确定所求和结果类型,为此我使用了 std::common_type (代码第29行), std::common_type 可以给出

2.3K20

【Rust笔记】浅聊 Rust 程序内存布局

于是, 类型对齐位数可由std::mem::align_of::()读取 类型存储宽度可由std::mem::size_of::()读取 若【对齐位数alignment】与【存储宽度size...于是, 对齐位数可由std::mem::align_of_val::(&T)读取 存储宽度可由std::mem::size_of_val::(&T)读取 存储宽度size对齐计算...所以,structalignment是全部字段alignment中最大。 字段union.Variant1是单字段元组结构体且唯一字段就是u16辨因子枚举。...第一个字段是u16类型分辨因子枚举。所以,Variant0.0.size = 2 Byte 第二个字段是u8类型数字。...所以,structsize是全部字段size之和。 字段union.Variant1是单字段元组结构体且唯一字段就是u16辨因子枚举

39620

C++17中新特性

, 新增了下面几种数据类型: 1. std::variant std::variant类型安全联合体,是一个加强版 union,variant支持更加复杂数据类型,例如map,string等等...2. std::optional std::optional表示一个可能存在。...如果通过optional返回创建实例,就会变得更加直观, std::optional 提供了下面几个方法: has_value() // 检查对象是否有 value() // 返回对象...,不存在时则抛出 std::bad_optional_access 异常 value_or() // 存在时返回,不存在时返回默认 3. std::any 一个类型安全可以保存任何容器...bool 表达式不能用 ++, -- 这两个自增(减)运算符了 c++17中异常已经成为了类型系统一部, 枚举直接列表初始化 结构化绑定 constexpr if 表达式 map支持merge和extract

4.8K30
领券