我读boost源代码笔记 第三篇 关于has_xxx.hpp

这次要说的是has_xxx.hpp, 这一段小小的代码虽然很简短,但是写得很精彩,不容错过,请大家留意了。

首先我们来谈谈has_xxx.hpp的作用, has_xxx就是用来判断某一个类中是否有xxx这个inner class,我们用has_type为例子说明问题(boost/mpl/aux_/has_type.hpp)

struct A

{

	typedef int type

};



struct B

{

};



/*

   ....

*/



boost::mpl::aux::has_type<A>::value;  // 1

boost::mpl::aux::has_type<B>::value;  // 0
大家在脑子里好好想想,这样神奇的功能是怎么样创造出来的呢.??反正我是想不出,呵呵,那就来看代码 boost/mpl/has_xxx.hpp就是一个范本,其中定义了宏
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait,name,default)
如果你的编译器和本人一样,上述的宏定义在 boost/mpl/has_xxx.hpp line: 164 在本人的编译器的版本中,最后一个参数,本人认为毫无作用,而如上文所说的has_type用到的就是这个宏来定义自身的功能
boost/mpl/aux_/has_type.hpp line:20
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_type, type, true)
现在一切的谜团都在BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF部分,就让我们来看看其中的神奇
boost/mpl/has_xxx.hpp line: 160
namespace boost { namespace mpl { namespace aux {

template< typename T > struct msvc71_sfinae_helper { typedef void type; };    // 1

}}}



#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) /

template< typename T, typename U = void > /  // 2

struct BOOST_PP_CAT(trait,_impl_) /  // 3

{ /

    BOOST_STATIC_CONSTANT(bool, value = false); /

    typedef boost::mpl::bool_<value> type; /

}; /

/

template< typename T > /

struct BOOST_PP_CAT(trait,_impl_)< /  // 4
      T /

    , typename boost::mpl::aux::msvc71_sfinae_helper< typename T::name >::type /   // 5

    > /

{ /

    BOOST_STATIC_CONSTANT(bool, value = true); /

    typedef boost::mpl::bool_<value> type; /

}; /

/

template< typename T, typename fallback_ = boost::mpl::bool_<default_> > /

struct trait /  // 6
    : BOOST_PP_CAT(trait,_impl_)<T> /

{ /

}; /

现在本人就对上述代码进行说明,我们参考对has_type的定义展开宏

BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_type,type,default)

首先在注释1处,定义了一个辅助类,这个类的作用是用来判断是否存在内嵌的类注释2处是对其中的impl_的类的定义,注意默认的typename U为void,而且事实上U并不被使用注释3处,BOOST_PP_CAT宏的作用是连接两个字符串,展开后就是 struct has_type_impl_{ 我们可以看到默认下传回的value是错误的,也即没有定义type 注释4,5处是一个特化,也就是通过注释1的辅助类判断是否有一个名为type的inner class,如果有选择4的定义,如果没有选择3 中的定义注释6中展开后为struct has_type,我们从这里可以看到两点

1. fallback_参数没有使用到。

2.has_type_impl_中第二个参数永远为void 我们可以看到,当6中的参数T带有T::type的时候,注释4处的定义更加符合,所以模板将根据注释4处的定义构造,value也就是1.反之将根据注释3处的定义构造,value为0 这样我们就可以在编译期判断某个类是否拥有某个名称的inner class了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值