?
meta_func的执行过程是在编译期完成的,实际执行程序时,是没有计算动作而是直接使用编译期的计算结果的。元函数只处理元数据,元数据是编译期常量和类型,所以下面的代码是编译不过的:
?
int i = 1, j = 2;
meta_func::value; //错误,元函数无法处理运行时普通数据
模板元编程产生的源程序是在编译期执行的程序,因此它首先要遵循C++和模板的语法,但是它操作的对象不是运行时普通的变量,因此不能使用运行时的C++关键字(如if、else、for),可用的语法元素相当有限,最常用的是:
?
enum、static const,用来定义编译期的整数常量;
typedef/using,用于定义元数据;
T、Args...,声明元数据类型;
template,主要用于定义元函数;
"::",域运算符,用于解析类型作用域获取计算结果(元数据)。
如果模板元编程中需要if-else、for等逻辑时该怎么办呢?
?
模板元中的if-else可以通过type_traits来实现,它不仅仅可以在编译期做判断,还可以做计算、查询、转换和选择。
?
模板元中的for等逻辑可以通过递归、重载、和模板特化(偏特化)等方法实现。
?
下面来看看C++11提供的模版元基础库type_traits。
?
3.type_traits
?
type_traits是C++11提供的模板元基础库,通过type_traits可以实现在编译期计算、查询、判断、转换和选择,提供了模板元编程需要的一些常用元函数。下面来看看一些基本的type_traits的基本用法。
?
最简单的一个type_traits是定义编译期常量的元函数integral_constant,它的定义如下:
?
template< class T, T v >
struct integral_constant;
借助这个简单的trait,我们可以很方便地定义编译期常量,比如定义一个值为1的int常量可以这样定义:
?
using one_type = std::integral_constant;
或者
?
template
struct one_type : std::integral_constant{};
获取常量则通过one_type::value来获取,这种定义编译期常量的方式相比C++98/03要简单,在C++98/03中定义编译期常量一般是这样定义的:
?
?
template
struct one_type
{
? ? enum{value = 1};
};
?
template
struct one_type
{
? ? static const int value = 1;
};
?
可以看到,通过C++11的type_traits提供的一个简单的integral_constant就可以很方便的定义编译期常量,而无需再去通过定义enum和static const变量方式去定义编译期常量了,这也为定义编译期常量提供了另外一种方法。C++11的type_traits已经提供了编译期的true和false,是通过integral_constant来定义的:
?
typedef ?integral_constant true_type;
typedef ?integral_constant false_type;
除了这些基本的元函数之外,type_traits还提供了丰富的元函数,比如用于编译期判断的元函数:
?
?
?
这只是列举一小部分的type_traits元函数,type_traits提供了上百个方便的元函数,读者可以参考http://en.cppreference.com/w/cpp/header/type_traits,这些基本的元函数用法比较简单:
?
?
#include
#include
?
int main() {
? std::cout << "int: " << std::is_const::value << std::endl;
? std::cout << "const int: " << std::is_const::value << std::endl;
?
? //判断类型是否相同
? std::cout<< std::is_same::value<<"\n";// true
? std::cout<< std::is_same::value<<"\n";// false
?
? //添加、移除const
? cout << std::is_same::type>::value << endl;
? cout << std::is_same::type>::value << endl;
?
? //添加引用
? cout << std::is_same::type>::value << endl;
? cout << std::is_same::type>::value << endl;
?
? //取公共类型
? typedef std::common_type::type NumericType;
? cout << std::is_same::value << endl;
?
? return 0;
}
?
type_traits还提供了编译期选择traits:std::conditional,它在编译期根据一个判断式选择两个类型中的一个,和条件表达式的语义类似,类似于一个三元表达式。它的原型是:
?
template< bool B, class T, class F >
struct conditional;
用法比较简单:
?
?
#include
#include
?
int main()?
{
? ?