author:
- luixiao1223
title: 认识template元编程
介绍
元编程是C++ template的一个副产物.它不是被发明的,而是被发现的.
而且它时图灵完备的.
TMP的好处
- 可以让事情更容易,没有它也许有的事情更困难甚至不可能
- TMP执行与C++编译期,可以把某些错误提前到编译期就可以发现.
- TMP因为运行在编译期,则更高效.较小的可执行文件,较短的运行期,较少的内存需求.
TMP的缺点
- 编译时间更长.
- 编程并不时很容易.
回顾前面的例子
template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d)
{
if ( typeid(typename std::iterator_traits<IterT>::iterator_category) ==
typeid(std::random_access_iterator_tag)) {
iter += d;
}else {
if (d >= 0) { while (d--) ++iter; }
else { while (d++) --iter; }
}
}
typeid发生于运行期,这是前面说到的缺点. 另外可能出现编译问题.
std::list<int>::iterator iter;
advance(iter, 10);//这里引发编译错误
void advance(std::list<int>::iterator& iter, int d)
{
if (typeid(std::iterator_traits<std::list<int>::iterator>::iterator_category) ==
typeid(std::random_access_iterator_tag)) {
iter += d; //这里发生编译错误
}
else {
if (d >= 0) { while (d--) ++iter; }
else { while (d++) --iter; }
}
}
C++编译期在看到list进行调用advance(iter,
10)的时候它必须保证iter+=d也需要可以执行.但是实际上是不能的.这就是为什么这里可能会发生编译错误的原因.
TMP是一个函数式的语言
template<unsigned n>
struct Factorial {
enum { value = n * Factorial<n-1>::value };
};
template<>
struct Factorial<0> {
enum { value = 1 };
};
int main()
{
std::cout << Factorial<5>::value;
std::cout << Factorial<10>::value;
}
这就是典型元编程递归写法.
TMP的几个应用
- TMP可以用于早起的错误检查
- 矩阵的运算
typedef SquareMatrix<double, 10000> BigMatrix;
BigMatrix m1, m2, m3, m4, m5;
BigMatrix result = m1 * m2 * m3 * m4 * m5;
如果是一般性的写法,则要创建多个临时变量.但是如果使用TMP技术.则不需要创建临时变量,并且速度有提升.
- policy-based design之TMP-based技术