开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
背景
定义在<type_traits>中,指定了一个特定类型的常量,是<type_traits>类型萃取中很基础的类型,在模板编程中有很重要的地位。
代码实现
gcc官网:gcc.gnu.org/
gcc代码下载:mirrors.tuna.tsinghua.edu.cn/help/gcc.gi…
gcc版本代码:gcc-7.5.0(branch分支)
文件位置:gcc/libstdc++-v3/include/std/type_traits
注意:以下的代码实现省略了一些宏定义部分,实际的代码还是参考gcc源码,这里仅用作相关原理分析。
/// integral_constant
template<typename _Tp, _Tp __v>
struct integral_constant
{
static constexpr _Tp value = __v;
typedef _Tp value_type;
typedef integral_constant<_Tp, __v> type;
constexpr operator value_type() const noexcept { return value; }
constexpr value_type operator()() const noexcept { return value; }
};
template<typename _Tp, _Tp __v>
constexpr _Tp integral_constant<_Tp, __v>::value;
/// The type used as a compile-time boolean with true value.
typedef integral_constant<bool, true> true_type;
/// The type used as a compile-time boolean with false value.
typedef integral_constant<bool, false> false_type;
template<bool __v>
using __bool_constant = integral_constant<bool, __v>;
template<bool __v>
using bool_constant = integral_constant<bool, __v>;
实现分析
integral_constant定义
从上面代码中我们可以看到,实际上integral_constant的作用就是存储一个特定类型的常量的值,结合类型萃取的原理,这里使用了类模板进行定义。其中:
- value_type被重命名为该特定类型;
- type被重命名为该模板类本身的类型;
- value用来存储该全局常量。
同时,还定义了两个常量表达式函数:
- 该特定类型的类型转换函数,直接返回存储的特定常量;
- 调用运算符重载函数,直接返回存储的特定常量。
value常量定义
这里还将对应该特定类型的特定值存储变量,使用类模板的方式进行定义,表明该变量全局可见。
true_type
定义bool变量的true值,后续将会有很多部分使用到该类型,可以直接返回true。
false_type
定义bool变量的false值,后续将会有很多部分使用到该类型,可以直接返回false。
bool_constant
integral_constant模板的一个具体使用,即_Tp为具体的bool类型,将在后面的类型萃取当中使用。
使用案例
#include <iostream>
#include <type_traits>
int main(){
typedef std::integral_constant<int32_t, 33> int_value_33_t;
typedef std::__bool_constant<true> my_true_t;
int_value_33_t test_value;
std::cout << "int_value_33_t:" << int_value_33_t::value << "\tcoversion function:"
<< test_value << "\tcaller function:" << test_value() << std::endl;
std::cout << std::boolalpha;
std::cout << "std::true_type:" << std::true_type::value << std::endl;
std::cout << "std::true_type:" << std::false_type::value << std::endl;
std::cout << "my_true_t:" << my_true_t::value << std::endl;
return 0;
}
可以看到,这里我们定义了自己的类型int_value_33_t(里面只存储了一个int32_t的常量数据33),使用__bool_constant定义了自己的my_true_t。
在变量打印时,对于int_value_33_t,我们可以通过访问类成员(static成员变量)的方式,也可以通过定义一个变量test_value,通过它的类型转换函数,调用符重载获取到这个存储的常量信息。
对于bool类型的变量,调用也是相同的,这里就不重复说明了。
总结
integral_constant通过定义一个特定类型特定值的类型模板,可以构造一个含有特定值的类型,外部可以通过类成员变量,类型转换函数,调用运算符获取到该特定值;其中bool类型设定了true_type和false_type,可以直接获取特定值类型,这几个特定的类型模板是类型萃取的基础类。