C++的type_traits是一套纯粹编译期的逻辑,可以进行一些类型判断、分支选择等,主要用于模板编程。使用type_traits并不难,但是我们希望能够更加深入了解其实现方式,与此同时,可以更进一步体验C++的模板编程。
本篇文章旨在引导大家自行实现type_traits的基础代码。
模板编程不像常规的代码,可以有if-else这些流控制语句,我们需要充分利用模板、模板特例、类型转换等特性来实现编译期的一系列判断和类型转换。
定义基础常量
第一步,我们需要定义true和false两个常量,所有的type_traits都基于此。我们的目的就是要用一个模板类型来表示是非,其中的value正好是这两个值。之后我们更高级的判断类型都是继承自这两个类型的其中一个,通过这种方式获取value值就可以获取true和false了。
如果听这个解释有点晕的话,不要紧,我们直接来看代码。这里需要注意的是,既然type_traits都是编译期行为,因此其成员只能是静态不可变成员(编译期就可以确定的成员)。
struct true_type {
static constexpr bool value = true;
};
struct false_type {
static constexpr bool value = false;
};
基础类型判断
有了基础常量,我们可以先做一些简单的类型判断,比如说判断这个类型是不是void。这里的思路是,针对于所有类型的模板,继承自false_type,而针对于void类型,我们给予一个模板特例,让他继承自true_type。这样一来,只有当类型是void的时候才会推导true,其他的就会推导false。请看例程:
template <typename>
struct is_void : false_type {
};
template <>
struct is_void<void> : true_type {
};
这里我们可以做一些简单的测试,来判断函数的返回值是否为void:
void test1();
int test2();
int main(int argc, const char *argv[]) {
std::cout << is_void<decltype(test1())>::value << std::endl; // 1
std::cout << is_void<decltype(test2())>::value << std::endl; // 0
return 0;
}
有了判断void的思路基础,不难写出判断其他类型的,比如说判断是否为浮点数,那么只需要对float,double,long double进行特殊处理即可,请看代码:
template

本文介绍如何从零开始实现 C++ 的 type_traits,包括基本常量定义、类型判断、类型处理、类型选择及判断类型是否相同等功能,并提供示例代码。
最低0.47元/天 解锁文章
1337

被折叠的 条评论
为什么被折叠?



