想看懂 stl 代码,先搞定 type_traits 是关键
type_traits在C++中是非常有用的技巧,可以说如果不懂type_traits,那根本看不懂stl相关代码,最近对type_traits比较感兴趣,于是找到了gcc的type_traits源码通读了一遍,总结一下。
type_traits称为类型萃取技术,主要用于编译期获取某一参数、某一变量、某一个类等等任何C++相关对象的类型,以及判断他们是否是某个类型,两个变量是否是同一类型,是否是标量、是否是引用、是否是指针、是左值还是右值,还可以将某个为某个类型去掉cv(const volitale)属性或者增加cv属性等等。
SFINAE
SFINAE技术,Substitution Failure is Not An Error,在编译期编译时,会将函数模板的形参替换为实参,如果替换失败编译器不会当作是个错误,直到找到那个最合适的特化版本,如果所有的模板版本都替换失败那编译器就会报错,以std::enable_if举个例子。
注释部分的代码如果打开就会编译失败,代码中明确规定了func函数只接收类型为int和double的参数,向func中传入其它类型参数编译器则会报错。
通过SFINAE技术可以完成很多有趣的事,比如根据参数类型做不同的定制化操作。
type_traits原理
type_traits最核心的结构体应该就是integral_constant,它的源代码如下:
基本上type_traits的每个功能都会使用到true_type和false_type,后续会介绍,这里先介绍代码中那两个operator函数的具体含义,operator type() const用于类型转换,而type operator()() const用于仿函数,见代码。
还有个主要的模板是conditional
当模板的第一个参数为true时type就是第二个参数的类型,当第一个参数为false时type就是第三个参数的类型,通过conditional可以构造出or and等功能,类似我们平时使用的带短路功能的|| &&,具体实现如下:
通过disjunction可以实现析取功能,type为B1, B2, B…中第一个value为true的类型。
再看看conjunction的实现
通过conjunction可以判断函数的参数类型是否相同,代码如下:
再举一些平时用的很多的例子,还可以判断某个类型是否有const属性,添加去除某个类型的左值引用或者右值引用,添加去除某个类型的const或者volatile。
is_const实现很简单,就是利用模板匹配特性,其它的is_volatile等类似
is_same的实现如下:
包括移除引用的功能, remove_reference
add_const, add_volatile, add_cv等的实现
欢迎私信或评论,我每天都会上线。
版权声明: 本文为 InfoQ 作者【程序喵大人】的原创文章。
原文链接:【http://xie.infoq.cn/article/79719d0662ed5ac40bbdd6d5f】。文章转载请联系作者。
评论