| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> c++ advanced(8) std::variant from beginner to expert -> 正文阅读 |
|
[C++知识库]c++ advanced(8) std::variant from beginner to expert |
目录 questions and existing problems item6 allocation at assignment removed? item1 different storage strategy std::variant(c17)在2004年boost 1.31.0库引入了variant,但是直到16年std::variant正式被引入标准库c++17 在看cpp reference的时候,我深恶痛绝的一点就是没有一个从浅到深的例子来说明应用场景,这也是我写博客的原因。 所以我们为什么需要variant? questions and existing problems假设一个场景,我们有一个类,类里面存储了两种信息分别是name,和index,但是这两种信息类型不同,在任何时候有且只有一种信息存在,因此我们有一个bool 类的has name来区分所含信息的种类。 同时为了涵盖所有的情况,我们不得不写出两个接口分别是getname和getindex。 int root.h file
这样就会导致三个问题:
第二个example say,我们有这样一个例子,我们根据数据流做一些操作,首先我们定义一个接口,然后我们指定一某一个操作为set_value。并且特化其中的put函数。
同样也有一些问题:
?一种解决方法如下:
这样写的好处显而易见:
variant: and VS or?那么什么是variant? 我们可以简单这样认为:
上面的代码代表S包含x和y两个type的两个变量
代表S包含XorY type; Why not Union有人会说Union不是也可以多个不同的type共享一块空间吗?实际上union本身就有一些缺陷:
Solution对于第一个example PersonID,我们可以这样写:
and that is it. 对于第二个example?command ,我们可以这样用variant替代:
《》内部是我们具体的实现类 variant in boost因为std引入了variant,因此boost种的意义不大,就简单说一下,
?variant in stdlibitem1 get && get_if保留了get<T>,并且多了一个get_if<T&>,如果不是就返回空, 否则返回指针
output:
我们也可以用idex来代替type,get_if和get用法不变 item2 std::visit保留了visit,但是还是需要用户自己写visitor函数:
item3 duplicate entries同一个variant可以有同样的type,比如这样:
很多人发现这样有问题,没办法初始化,其实方法简单,用emplace(c14)就可以:
这样就可以区分是扔进去的第一个还是第二个了……当然实际开发中应该很少这么写(sad)? item4 no special recursion也就是说没办法写递归,比如我们定义二叉树:
item5 std::monostateboost库种原本为boost::blank,std种为monostate,熟悉英语的应该能猜到这叫单一状态 ,本身它也只起一个占位的作用,为无法初始化的variant提供一个可以初始化的机会;
我们可以这样写:
item6 allocation at assignment removed?类模板 但是搞笑的是,既然已经扔出异常了,我们通常情况下程序会直接矶钓,根本不会有机会让我们去这样检查,所以基本上这个东西用不到。乐 overload lambda for visit下面展示一种酷酷的visitor的写法:
其实visitor底部就是index:
还是推荐大多多用index啊。 other substitutionstd:optional(c17)在实际开发中,我们会n次地去判断内容是否为空,optional提供了一种更优雅的方式来判断内容。
std:any(C17)any不需要我们指定template,类似于variant。
尽管这样更方便,但是也意味着更不安全,而且会有性能损失,因此还是建议大家使用variant item1 different storage strategy还有个更重要的区别就是存储方式,variant意味着本身是个safe的union,但是any不是这样存储的,any 的source code种有这样一部分:
?看一下big和samll storage就能发现对于大型的struct,存储方式为void*而不是union,是通过动态分配的方式给出的。
如果我们gose deeper,就会发现 small storage的大小大概为32byte,也就是说大于32byte的会用动态分配的策列。
item2 copy while? any_cast这也就意味着,我们在any_cast的时候永远都是获取的右值,是一个新的值,这在variant的get种是可以实现的。
如果我们仍然希望得到引用,那么这样写回提升一点点性能:
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/14 14:27:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |