找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5098|回复: 0

对《C++ TMP》第三章的twice函数的讨论

[复制链接]
发表于 2008-9-20 17:36:05 | 显示全部楼层 |阅读模式
《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));}

我还是比较喜欢最后一种写法,你呢?
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-3 10:45 , Processed in 0.015593 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表