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_listallocator

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




。。看来这个问题是有点奇葩,有点像脑筋急转弯,我一描述大家一听都有道理,结果其实我们都被唬到了。。最后

仔细想想原来就这么简单。




原创粉丝点击