对《C++ TMP》第三章的twice函数的讨论
《C++ Template Metaprogramming》的第三章举了两个例子,一个是量纲分析,另一个是高级元函数twice。量纲分析的实现比较清楚,对我来说是大开了一回眼界,onlyxuyang已经有一个帖子介绍了;但是对于高级元函数twice的实现,我觉得弄得有点太复杂了。先看看twice的定义:twice(f, x) := f(f(x)),要求提供一个twice的实现,然后从boost::add_pointer出发,得到add_two_pointers。
书中给出的twice<F, X>要求F是元函数类(metafunction class),而add_pointer是一个元函数,因此还要手工从boost::add_pointer生成相应的元函数类,然后才可以使用twice。
代码如下:
struct add_pointer_f{ template <class T> struct apply : boost::add_pointer<T> {};}; template <class F, class X>struct twice : F::template apply<typename F::template apply<X>::type>{}; template <class X>struct add_two_pointers : twice<add_pointer_f, X>{};
接着,书中示例了如何用mpl::lambda元函数来从boost::add_pointer就地生成twice所需的元函数类,这样就可以省掉add_pointer_f的手工定义。代码如下:
template <class F, class X>struct twice : F::template apply<typename F::template apply<X>::type>{}; template <class X>struct add_two_pointers : twice<typename mpl::lambda<boost::add_pointer<_1> >::type, X>{};
最后,书中展示了如何用mpl::apply元函数替换掉在twice中的手工调用apply。代码如下:
template <class F, class X>struct twice : mpl::apply<F, typename mpl::apply<F, X>::type>{}; template <class X>struct add_two_pointers : twice<typename mpl::lambda<boost::add_pointer<_1> >::type, X>{};
以上几种实现方法,里面的template、typename、::type还有类括号一大堆,看得我脑袋发晕。我想,为什么twice<F, X>中的F一定要是class,而不能是template呢?C++模板不是还支持模板模板参数(template template parameter)吗?如果让F可以是一个模板模板参数,代码应该更简单、直接,也更容易读一些。如下:
template <template <typename> class F, class X>struct twice : F< typename F<X>::type >{}; template <class X>struct add_two_pointers : twice<boost::add_pointer, X>{};
以上四种实现方法,都可以顺利通过以下测试:
int main(){ typedef add_two_pointers<int>::type intpp;BOOST_STATIC_ASSERT((boost::is_same<intpp , int**>::value));}
我还是比较喜欢最后一种写法,你呢?
页:
[1]