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

为什么std::variant实现对于空类型的variant需要超过1个字节?

std::variant是C++17标准库中引入的一种数据类型,它可以存储多个不同类型的值,类似于联合体(union)。然而,与传统的联合体不同,std::variant提供了类型安全和异常安全的访问方式。

为了实现对于空类型的variant,std::variant需要超过1个字节的存储空间。这是因为std::variant需要存储额外的信息来跟踪当前存储的是哪个类型的值。

具体来说,std::variant通常使用一个额外的整数来表示当前存储的是哪个类型的值。这个整数被称为“索引”或“标签”,它指示了当前存储的值的类型。当std::variant被赋值为某个类型的值时,它会更新这个索引值。

对于空类型的variant,即std::monostate,std::variant需要使用一个额外的标志位来表示当前是否存储了值。这个标志位通常被称为“是否有效”标志。当std::variant被赋值为空类型时,它会将这个标志位置为无效。

由于需要存储额外的信息,std::variant对于空类型的variant需要超过1个字节的存储空间。

std::variant的优势在于它提供了一种类型安全的方式来存储多个不同类型的值,并且可以方便地进行访问和操作。它可以用于各种场景,例如状态机、解析器、事件处理等。

腾讯云提供了云计算相关的产品和服务,其中包括云服务器、云数据库、云存储、人工智能等。具体推荐的腾讯云产品和产品介绍链接地址可以参考腾讯云官方网站:https://cloud.tencent.com/

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

相关·内容

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

使用函数对象作为访问器 使用函数对象作为访问器,我们需要将variant变量中支持的类型都在函数对象中进行实现,即对variant对象支持所有类型的operator()重载。....>; 跟函数对象一样,我们需要对variant中所有的类型都实现对应的lambda函数,然后使用overload来访问variant。...接下来,就是本节最核心的部分,如下: std::variant v; 因为需要实现多态,而多态是基于多种类型的,所以我们声明一个变量v,其类型可以是Base对象或者Derived...因此,您可能会丢失 90 个字节 每个多态操作都需要实现一个对应的visit 结语 在本文中,我们研究了实现多态的三种方式,其中着重对虚函数机制和std::variant机制进行了分析。...对于std::variant,其是值语义的,这就避免了虚函数机制所需要的堆上分配,进而提高系统性能。但是其预先需要了解所有可能的类型,在扩展方面不是很友好,而虚函数机制则没有此类问题。

96620

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

它们的内存布局在不同型号的设备上略有差异 在非x86设备上,存储宽度size = 对齐位数alignment(即,倍数N = 1) 在x86设备上,因为设备允许的最大对齐位数不能超过4字节,所以alignment...来自【标准库】的零宽度数据类型包括但不限于: () 单位类型 — 模拟“空”。 std::marker::PhantomData — 绕过“泛型类型形参必须被使用”的编译规则。...field.offset 定义:每个字段首字节地址相对于上一层数据结构首字节地址的偏移字节数 规则: field.offset必须是field.alignment自然数倍。...但在Rust内存布局下,需要调用专门的标准库函数std::intrinsics::transmute()才能达到相同的目的。...声明一个游标变量,以实时跟踪(相对于结构体首字节地址)的偏移量。 let mut offset_cursor = 0; // 3. 按照字段在源代码中的词法声明次序,逐一遍历每个字段。

60720
  • C++中std::variant用法详解

    std::variant 是一个类型安全的联合体,可以存储固定集合中的任意类型的值。这使得 std::variant 成为处理那些可能需要存储不同类型数据的情况的理想选择。...因此,在性能敏感的代码中使用时应当谨慎。 std::monostate 对于可能需要默认构造且不持有任何值的 std::variant,可以使用 std::monostate 作为其类型之一。...这是一个空的结构体,用于提供默认构造行为。...std::variant 提供了一种安全、灵活的方式来存储解析后的数据,从而简化代码并增强其健壮性。 状态机:在实现状态机时,每个状态可能需要不同类型的数据来描述。...命令模式:在实现命令模式时,如果命令的参数类型多样,std::variant 可以作为一个通用的参数容器,提供统一的接口而隐藏实现细节。

    1.6K10

    如何优雅的使用 std::variant 与 std::optional

    值表达当前的oneof所用的是哪个类型, 而optional对于bool, int等值类型则额外附加一个bool变量(has flag), 用来表达对应值是否已经被设置....; } 1.4 更安全的获取方法 除了会引发异常的std::get, 也有无异常的 std::get_if() 方法, 当然, 需要自行判断返回的指针类型是否为空: int* i = std::...).out1 << endl; 3. std::visit() 方式 对于optional来说, 简单的获取值的方法足够用了, 但对于更复杂的std::variant, 上面介绍的访问方式在std:...与operator的实现基本类似. 3.2. overloads方式访问std::variant 除了上述介绍的方法, 有没有更优雅的使用std::visit的方式呢?...方式完成对std::variant的访问, 以及相关的ponde的使用示例代码, 和介绍了一个利用c++17特性实现的overloaded特性.

    3.8K10

    c++17好用的新特性总结

    比如我想实现一个函数将不同类型的输入转化为字符串,在c++17之前需要写三个函数去实现,而c++17只需要一个函数。...平时代码中可以大规模使用的一个特性。其实对于string的争论一直没有停止过,很多人认为string是字节串而不是字符串,因为string是可以改变的,这一切争论到C++17可以停止了。...与union相比有两点优势: 可以存储复杂类型,而union只能直接存储基础的POD类型,对于如std::vector和std::string就等复杂类型则需要用户手动管理内存。...类型安全,variant存储了内部的类型信息,所以可以进行安全的类型转换,c++17之前往往通过union+enum来实现相同功能。...需要注意的是,c++17只提供了一个库级别的variant实现,没有对应的模式匹配(Pattern Matching)机制,而最接近的std::visit又缺少编译器的优化支持,所以在c++17中std

    3.4K10

    C++17 std::variant 详解:概念、用法和实现细节

    这种特性为开发者提供了极大的便利,在面对需要处理多种不同类型数据的场景时,std::variant提供了一种灵活且高效的解决方案,使得代码编写更加简洁、安全。...> myVar;与传统联合体union的区别传统的C风格联合体union虽然也能实现存储不同类型的值,但与std::variant相比,存在诸多劣势。...首先,std::variant具备类型安全性,而union则需要开发者手动管理数据成员的活跃性。在使用union时,如果错误地访问了当前未存储的类型数据,就会导致未定义行为。...std::string, double> v(123); v = "HelloWorld"; return 0;}判断variant中对应类型是否有值为了确保类型安全,经常需要判断...不使用虚表和继承实现的多态通过std::variant结合std::visit(本文未详细介绍),可以实现一种不依赖虚表和继承的多态机制。

    6500

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

    比如我想实现一个函数将不同类型的输入转化为字符串,在 c++17 之前需要写三个函数去实现,而 c++17 只需要一个函数。...且对于 lock/iterator 等涉及并发/RAII 的类型更容易保证程序的正确性。...与union相比有两点优势: 可以存储复杂类型,而 union 只能直接存储基础的 POD 类型,对于如std::vector和std::string就等复杂类型则需要用户手动管理内存。...类型安全,variant 存储了内部的类型信息,所以可以进行安全的类型转换,c++17 之前往往通过union+enum来实现相同功能。...return {ret}; } 需要注意的是,c++17 只提供了一个库级别的 variant 实现,没有对应的模式匹配(Pattern Matching)机制,而最接近的std::visit又缺少编译器的优化支持

    2.7K20

    冷饭新炒:理解JDK中UUID的底层实现

    这里只需要记住UUID几个核心特定: 全局时空唯一性 固定长度128比特,也就是16字节(1 byte = 8 bit) 分配速率极高,单机每秒可以生成超过1000万个UUID(实际上更高) 下面就JDK...这个数字大概可以这样估算:如果每纳秒产生1兆个不相同的UUID,需要花费超过100亿年才会用完所有的UUID。...中间变量msb或者lsb在提取字节位进行计算的时候: 先进行左移8位确保需要计算的位为0,已经计算好的位移动到左边 然后右边需要提取的字节data[i]的8位会先和0xff(补码1111 1111)进行或运算...这里总结一下随机数版本UUID的实现步骤: 通过SecureRandom依赖提供的安全随机数接口获取种子,生成一个16字节的随机数(字节数组) 对于生成的随机数,清空和重新设置version和variant...: 通过输入的命名字节数组基于MD5算法生成一个16字节长度的随机数 对于生成的随机数,清空和重新设置version和variant对应的位 把重置完version和variant的随机数的所有位转移到

    1.2K50

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

    ,标准模板库中新添加的并行算法,新的文件系统库,以及3个新的数据类型:std::any, std::optional, 和 std::variant.让我们来了解一下其中的细节.... std::u32string_view std::basic_string_view 你也许会有疑问:为什么我们需要 std::string_view 呢(...而高效的原因在于 std::string_view 的创建成本很低, 仅需要两个数据:字符序列的指针以及字符序列的长度. std::string_view 以及他的3个"兄弟"类型(指 std::wstring_view...(译注: 单子(Monad) 是函数式编程编程的概念,简单理解的话可以看看这里) 我们再来看下 std::variant. std::variant std::variant 是一个类型安全的联合体(union...).一个 std::variant 实例存储着其指定类型中某一类型的数据,并且 std::variant 的指定类型不能是引用类型,数组类型以及 void 类型,不过 std::variant 可以指定重复的数据类型

    1.3K10

    C++那些事之有趣的面试问题

    最近想出一些有趣的问题,做一个小总结,你能回答上来几个? 注:完整答案会在星球揭秘。 问题1:std::variant构造函数会调用几个类型构造,1个?2个?n个?...当 std::variant 包含类型不具有默认构造函数时会发生什么? 如何指定 std::variant 的初始值类型? 问题2:下面代码可以正常运行吗?...::variant a1; 相关问题: 如何为 std::variant 添加具有默认构造函数的类型?...当 std::variant 的类型列表中没有默认构造函数时,有哪些解决方案? 如何显式构造 std::variant 以避免默认构造问题? 问题3:什么是monostate,解决了什么问题?...相关问题: defer_lock_t 的使用场景和实现机制是什么? try_to_lock_t 如何处理互斥锁的尝试锁定? adopt_lock_t 在接管已有锁的所有权时有什么注意事项?

    13810

    VBA数据类型Variant

    我以前一直好奇为什么能有什么数据都可以保存的类型,现在对内存知识有了一定了解才知道,其实说到底,Variant底层也是一种数据结构,16个字节分别会有不同的意义,对于一些VBA里的对象复制给Variant...至于通过地址怎么就能判断出对象的具体类型就不大清楚了! 所以想知道Variant的16个字节具体代表了什么,我们只需要让它保存不同的数据类型,然后查看16个字节的变化就可以了。...Variant16字节是如何分配的?...前8字节 b0:标识数据类型(也就是VarType返回的数字) b1:标识后8字节是数据还是指针 - 0x00 8-15数据类型的是数据本身,String是地址 - 0x40 8-11存的是数据地址...,String是地址的地址 - 0x20 8-11存的是数组地址 - 0x60 8-11存的是数组地址的地址 后8字节8-15:数据或地址 Sub TestVariant() Dim

    1.8K30

    类型安全的瑞士军刀——std::variant

    前言 当需要在同一块内存区域中存储不同类型的值且在任何时刻只会存储其中的一种类型时,联合体(union)总是作为首要选择,但是联合体存在如类型安全差、不支持构造函数和析构函数等缺点。...std::variant作为一个多形态的容器,可以容纳一组预定义类型的其中之一,任何时候它都只存储其中一个类型的有效值,提供了严格的类型安全保证。 联合体通过.指定变量名进行变量存取,如下示例代码1。...; } return 0; } 上述代码展示了如何创建一个能存储int和std::string类型的std::variant,并根据需要在两者之间切换。...值得注意的是,直接通过std::get(myVariant)访问值时,必须确保当前存储的类型与T一致,否则会抛出std::bad_variant_access异常。...)和一个std::variant实例,根据variant中实际存储的类型调用访问者的相应重载方法。

    15110

    std::variant和policy-based design的化学反应

    前言 通常来讲,C++的多态存在静态多态(函数重载)和动态多态(指针或引用+虚函数表),但是C++17引入新的特性——std::variant,为多态提供了新的实现方式。...同时,也为policy——based design提供了新的书写方式。 std::variant简介 std::variant在之前的文章中讲过,简单叙述如下,如需详细了解,可翻看前文。...std::variant是类型安全的多形态容器,存储预定义类型中的一个,结合std::visit函数可以根据variant中实际存储的类型调用访问者的相应重载方法。...用法讲解见类型安全的瑞士军刀——std::variant。 Policy-based design Policy-based design(基于策略的设计)是一种现代C++编程中的高级泛型编程技术。...当使用std::variant实现该模式时,浅显易懂,较继承和模板的实现方式具有更高的可读性。

    8510

    Java运行时数据区域

    它用于存储下一条所要执行的 JVM 指令的执行地址。 (2)、为什么需要程序计数器?...在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成...如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地 址;如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。...JVM的字节码解释器就需要通过改变程序计数器的值来明确下一条应该执行什么样的字节码指令。 (5)、程序计数器为什么是线程私有的?...每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 (2)、为什么需要虚拟机栈?

    33840

    C++多态性能测试:CRTP vs std::variant vs virtual

    C++多态性能测试:CRTP vs std::variant vs virtual 多态是面向对象编程的一个重要概念,它使得单一接口能够代表不同的类型。...C++提供了几种实现多态性的方式,本文将会讨论三种场景的多态: 虚函数:在C++中实现多态性的传统方式是使用虚函数。这涉及使用基类和派生类来实现特定的实现。...std::variant:在C++17中引入的std::variant,它实现了一种无需继承的多态性。...CRTP(Curiously Recurring Template Pattern):CRTP是一种比较特殊的技术,它通过模板的奇特递归模式实现多态性。...测试的组合场景如下: 单纯crtp crtp + std::variant virtual std::variant + std::visit std::variant + std::get_if std

    41110

    BSTR LPSTR LPWSTR CString VARIANT COleVariant variant t CC

    三、VARIANT、COleVariant 和_variant_t 在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输...BSTR * pbstrVal; // VT_BYREF|VT_BSTR. }; }; 显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型。...对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子: VARIANT va; int a=2001; va.vt=VT_I4; //指明整型数据...如果需要默认为空值,则将其初始化为空字符串 [“”],如下所示: void AddCustomer( const CString& name, const CString& address, const...串的基本运算 对于串的基本运算,很多高级语言均提供了相应的运算符或标准的库函数来实现。

    1.1K20

    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.4K20

    EOS行为核心:解析插件chain_plugin

    get_table_rows_ex,这是非常重要的一个函数,需要源码分析: /** * 检索table的核心函数 * @tparam IndexType 模板类,支持不同的索引类型 * @param p...result.more = true; } } return result; } 继续回到get_table_rows接口函数体,如果不是主键,则需要按照键类型来区分处理,键类型包括i64...值超过了assert数据类型的大小,说明是无效数据。...实际的转换工作是由binary_to_variant函数执行的。总结这两个接口实现函数可以发现,binary对应的就是二进制数据格式,而variant变体对应的是json格式。 19....该接口的入参类型是一个变体对象variant_object,也就是说它没有像其他接口那样特别声明参数结构,而是在函数实现中,加入了对象的构造过程,参数对象最终通过abi_serializer::from_variant

    91220

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

    由于std::vector是自动扩容的,当存入大量的数据后,并且对容器进行了删除操作,容器并不会自动归还被删除元素相应的内存,这时候需要手动运行shrink_to_fit()释放这部分内存。...和list的双向链表的实现不同,forward_list使用单向链表进行实现,提供了O(1)复杂度的元素插入,不支持快速随机访问,也是标准库容器中唯一一个不提供size()方法的容器。...当不需要双向迭代时,具有比list更高的空间利用率。...,除了std::pair外,似乎没有现成的结构能够用来存放不同类型的数据。...: int index = 1; std::get(t); //非法 c++17引入了std::variant,提供给variant的类型模版参数 可以让一个variant从而容纳提供的几种类型的变量

    85720

    ​【刘文彬】 EOS行为核心:解析插件chain_plugin

    get_table_rows_ex,这是非常重要的一个函数,需要源码分析: /** * 检索table的核心函数 * @tparam IndexType 模板类,支持不同的索引类型 * @param p...result.more = true; } } return result; } 继续回到get_table_rows接口函数体,如果不是主键,则需要按照键类型来区分处理,键类型包括i64...值超过了assert数据类型的大小,说明是无效数据。...实际的转换工作是由binary_to_variant函数执行的。总结这两个接口实现函数可以发现,binary对应的就是二进制数据格式,而variant变体对应的是json格式。 19....该接口的入参类型是一个变体对象variant_object,也就是说它没有像其他接口那样特别声明参数结构,而是在函数实现中,加入了对象的构造过程,参数对象最终通过abi_serializer::from_variant

    1.1K20
    领券