Effective C++ 条款48

本节条款:了解模板元编程

本节条款是对模板元编程的简单介绍,让读者知道有这么一种编程方式,更确切的说是一种技术。 那么,什么是模板元编程?模板元编程有什么好处?按照作者的原话就是: 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;elsewhile(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;elsewhile(d++) –iter;}}

上述的语句iter+=d;将无法通过编译,,原因是list<int>::iterator的iterator_category类型是bidirectional的,而bidirectional不存在+=运算符的操作,所以编译不通过。虽然实际运行中if不会内不会执行,但是编译器却需要在编译期间对所有语句进行编译。

对于TMP编程,我得到的收获大概就这么多。

如果我们想要更多的玫瑰花,就必须种植更多的玫瑰树。

Effective C++ 条款48

相关文章:

你感兴趣的文章:

标签云: