本节条款是对模板元编程的简单介绍,让读者知道有这么一种编程方式,更确切的说是一种技术。
那么,什么是模板元编程?模板元编程有什么好处?按照作者的原话就是:
1. TMP可将工作由运行期转移到编译期,因而得以实现早期错误侦测或者更高的执行效率。
2. TMP可被用来生成“基于政策选择组合”的客户定制代码,也可以用来避免生成对某些特殊类型并不适合的代码。
说原理容易让人不知所云,来一段作者的代码,大家看看。
template <int N>
struct Factorial
{
enum
{
value = N * Factorial<N - 1>::value
};
};
template <>
struct Factorial<0>
{
enum
{
value = 1
};
};
int main()
{
cout << Factorial<5>::value << endl;
}
从上面的代码我们可以看到我们实现了一个阶乘函数。通过调用语句Factorial<5>::value
就可以得出我们需要的结果,这段代码的推动力就是编译期间的模板实例化过程。收尾工作由特例化模板完成。
如果我们对条款47掌握较好的话,我们就能再次感受模板元编程的优点,可以进行编译期间的类型识别和编译期间的函数分配。
我们知道条款47也能通过typeid方式实现,可是typeid方式有的时候却会出现编译不通过的错误,如下代码:
template<typename Iter, typename DistT>
void advance(IteT& 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;
}
}
如果我们调用语句std::list<int>::iterator iter; advance(iter,10);
实例化advance函数,这时候实例化过程如下:
void advance(std::list<int>::iterator& iter,int d)
{
if(typeid(typenamestd::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;
}
}
上述的语句iter+=d;
将无法通过编译,原因是list<int>::iterator
的iterator_category类型是bidirectional的,而bidirectional不存在+=运算符的操作,所以编译不通过。虽然实际运行中if不会内不会执行,但是编译器却需要在编译期间对所有语句进行编译。
对于TMP编程,我得到的收获大概就这么多。
原文地址:http://blog.csdn.net/u011058765/article/details/46453745