C++17 std::in_place_type, std::in_place_index_t, std::in_place_type_t 这些的用法
来源:互联网 发布:二维动漫制作软件 编辑:程序博客网 时间:2024/06/07 11:49
C++17标准提供了三个新东西,
std::optional,
std::variant,
std::any
概念和使用方法都挺简单的。
可以参考cppreference等各大网页。
但是如果点开看的话,会发现有几个构造函数有点奇怪,用到了
std::in_place,
std::in_place_type,
std::in_place_index,
std::in_place_t,
std::in_place_type_t,
std::in_place_index_t
这些奇怪的东西。
其实都挺简单的,但是还是有一点小的需要注意的地方,我第一次就有点懵,折腾了半天,现在发出来一个是帮助自
己记忆,一个是免得别人再耽误时间了。
如果需要看示例代码,可以看最下面我附上的知乎链接。(其实没必要看,挺简单的)
看cppreference解释,这些是用来强调原位构造的tag,消除歧义。
乍一看其实还是有点懵,
举例来说
std::variant的构造函数,见http://en.cppreference.com/w/cpp/utility/variant
第五个
template<class T, class... Args >constexpr explicit variant(std::in_place_type_t<T>,Args&&... args);
意思是以T类型的初始值来初始化variant,这个值是什么呢? 用args来构建出来的T,就是这个初始值。
第七个
template<std::size_tI, class... Args >constexpr explicit variant(std::in_place_index_t<I>,Args&&... args);
意思是以variant的模板参数第I个的类型来初始化variant,值是args构建出来的T
这里看英文写的其实有点含糊。。可能不是英语母语的原因吧。。刚开始有点搞不清,到底是以args来构建T,还是以
args的各个值来构造variant的各种类型的值。
后来拿代码试了试,确认的确是用args来构造T。
想想也对,variant是当作类型安全的union用的,怎么可能一下初始化所有类型的值。
注意第六个和第八个
template<class T, class U, class... Args >constexpr explicit variant(std::in_place_type_t<T>,std::initializer_list<U>il, Args&&... args);
template<std::size_tI, class U, class... Args >constexprexplicit variant(std::in_place_index_t<I>,std::initializer_list<U>il, Args&&... args);
同时用到了std::initializer_list和...Args,乍看上去也挺懵的。都用了initializer_list了,干嘛还加个参数包?
随便用一个不就行了?
其实这里是我自己犯迷糊了,initializer_list是同类型的一串值,和参数包还有 以大括号初始化的时候传进去一堆类型
不同的值,那个不一样。尽管长得挺像的,但是不是一个概念。
initializer_list完全可以和别的参数一起用,来构造一个东西。
举例来说std::vector有一个构造函数可以接受initializer_list和allocator
见vector的第八个构造函数
http://en.cppreference.com/w/cpp/container/vector/vector
至于为什么initializer_list不能被包含在参数包里,要单独列出来,可以去查,我也记得不太清楚。好象是模板参数推
导歧义的原因?
其他的我就不详细说了,理解了一个以后,别的都挺直白的。
比如说std::in_place,用来明确要求使用某个std::optional的构造函数等
还有一点要注意的是
std::in_place_type_t是一个模板类(template class,是一个特殊的class)
std::in_place_type是一个模板变量(template variable,是一个特殊的variable)
变量模板是C++17的新特性,可以自己去查。
注意到
std::in_place_type的定义
template <class T> struct in_place_type_t { explicit in_place_type_t() = default;};template <class T>inline constexpr std::in_place_type_t<T> in_place_type{};
是inline constexpr的,所以尽量使用std::in_place这种模板变量,应该会比构造一个std::in_place_type_t的实例要更
效率一点,不过也不能确定,tag只是一个空类,说不定构造就被优化了呢?(inline variable也是C++17的新东西,
可以见我另一篇博客http://blog.csdn.net/zhangfengz1995/article/details/78143360)
相关的网页
我在知乎的自问自答
https://www.zhihu.com/question/66032208
还有stackoverflow的自问自答。。。
https://stackoverflow.com/questions/46508850/why-is-there-a-constructor-accepting-both-initializer-list-and-a-parameter-pack
。。看来这个问题是有点奇葩,有点像脑筋急转弯,我一描述大家一听都有道理,结果其实我们都被唬到了。。最后
仔细想想原来就这么简单。
- C++17 std::in_place_type, std::in_place_index_t, std::in_place_type_t 这些的用法
- std
- std
- std
- std::unique_ptr和std::shared_ptr的用法
- std::copy 的用法
- std::string的用法
- std::map的用法
- std::string的用法
- std::string的用法 .
- std::stringstream的用法
- std::mutex的用法
- std::function的用法
- C++/STL std::string 的用法
- std::bind std::function 用法
- std::string的基本用法
- using namespace std 的用法
- using namespace std 的用法
- 我的第一篇博客
- 【每周论文】Paragon: QoS-Aware Scheduling for Heterogeneous Datacenters
- 关于java中快速排序和冒泡排序的小结
- 换一个角度来看Hadoop集群
- Thinkphp封装P方法。实现分页效果
- C++17 std::in_place_type, std::in_place_index_t, std::in_place_type_t 这些的用法
- 简述默认网关冗余协议
- Android内存泄露
- DOCKER push失败:denied: requested access to the resource is denied
- linux 网站
- 交换机相关高级特性
- SQL Server2008 R2设置sa登录
- 各种电容器的优缺点
- Windows下CMD中文乱码问题解决方法