我读boost源代码笔记 第二篇 is_function代码的阅读

type_traits里面有着很多的文件,很难一一阅读完,这里说明is_function这个metafunction和他们所涉及到的一些其他的源文件,愿能起到抛砖引玉的作用吧。

 首先来说的就是is_function,我们首先查阅到 boost/type_traits/is_funcion.hpp line 64 struct is_function_impl 就是is_function的实现(boost源代码里面有许多这样的东西)

其中boost/type_traits/is_funcion.hpp line 64 - 77是主要部分 注意我们常见的int (*)(int,int)是函数的指针,而int (int,int)才是函数而is_function的只是对后者才返回1

boost/type_traits/is_funcion.hpp line 71 中is_function_ptr_tester在 boost/type_traits/detail/is_function_ptr_tester.hpp 中定义,可以判断是否是函数指针,我们打开 boost/type_traits/detail/is_function_ptr_tester.hpp 后发现了一大堆乱其八糟的模板函数,注意只有声明没有定义,这些函数之间的关系是重载的关系,由编译器决定哪个函数被使用,其中 boost/type_traits/detail/is_function_ptr_tester.hpp line 29

// Note it is acceptible to use ellipsis here, since the argument will

// always be a pointer type of some sort (JM 2005/06/04):

no_type BOOST_TT_DECL is_function_ptr_tester(...);

 

定义了一个默认为非函数指针的函数版本,而其后定了了是函数指针的版本

我们阅读is_function_ptr_tester.hpp的时候要注意以下两点

1.所谓判断是否是函数,是通过大量的丑陋的重复的代码判断的(is_function_ptr_tester.hpp line 37开始)。而这些丑陋的代码也仅仅支持到函数参数个数最多为25的函数,也就是说

boost::is_function<int (int,int,int,int,int,int,int,int,int,int,

		int,int,int,int,int,int,int,int,int,int,

		int,int,int,int,int,int)>::value  //26个参数,value值为0



boost::is_function<int (int,int,int,int,int,int,int,int,int,int,

		int,int,int,int,int,int,int,int,int,int,

		int,int,int,int,int)>::value  //25个参数,value值为0

2.为什么is_function_ptr_tester.hpp中对这些函数之进行了声明? 我们可以从 boost/type_traits/is_funcion.hpp line 71看到

value = sizeof(::boost::type_traits::is_function_ptr_tester(t))

        == sizeof(::boost::type_traits::yes_type)

上述代码是仅在编译时判断,是通过判断返回值类型的大小来确定

boost/type_traits/detail/yes_no_type.hpp中定义了 type_traits::yes_type和type_traits::no_type boost/type_traits/detail/yes_no_type.hpp line 17

typedef char yes_type;

struct no_type

{

   char padding[8];

};

我们可以知道yes_type的size是1,而no_type的size是8通过判断可以知道是否范围值为yes_type,从而可以判断该指针是否是函数指针 因为不涉及到运行时,因此仅仅需要声明而不需要定义

boost/type_traits/is_funcion.hpp line 63中

struct is_function_impl

{

#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)

#pragma warning(push)

#pragma warning(disable:6334)

#endif

    static T* t;

    BOOST_STATIC_CONSTANT(

        bool, value = sizeof(::boost::type_traits::is_function_ptr_tester(t))

        == sizeof(::boost::type_traits::yes_type)

        );

#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)

#pragma warning(pop)

#endif

};

那几个#pragam warning只是关闭了warning选项的,不用理他们

其中BOOST_STATIC_CONSTANT的定义在boost/config/suffix.hpp line 350

#     define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment

也就是说上述代码展开后是

template <type T>

struct is_function_impl

{

	static T* t;

	static const bool value = (sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)

}

而boost/type_traits/is_funcion.hpp line 80

template <typename T>

struct is_function_impl<T&> : public false_type

{};

则将全部的引用类型定义为false,其中false_type在boost/type_traits/integral_constant.hpp line:48中定义了。

现在我们知道了is_function的实现细节,只用把它包装起来就可以了 boost/type_traits/is_funcion.hpp line 89

boost/type_traits/detail/bool_trait_def.hpp line 67

#define BOOST_TT_AUX_BOOL_TRAIT_DEF1(trait,T,C) /

template< typename T > struct trait /

    BOOST_TT_AUX_BOOL_C_BASE(C) /

{ /

    BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(C) /

    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,trait,(T)) /

}; /

/

BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,trait) /

其中BOOST_MPL_AUX_LAMBDA_SUPPORT因为使用的是vc8定义为空 BOOST_TT_AUX_TEMPLATE_ARITY_SPEC也因为使用vc8定义为空 而BOOST_TT_AUX_BOOL_C_BASE在bool_trait_def.hpp line 62定义

#ifndef BOOST_TT_AUX_BOOL_C_BASE

#   define BOOST_TT_AUX_BOOL_C_BASE(C) : ::boost::integral_constant<bool,C>

#endif 

BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL在bool_trait_def.hpp line 59中定义,伟大的vc8中定义还是为空所以,宏展开为

template< typename T > is_function

: ::boost::integral_const<bool,::boost::detail::is_function_impl<T>::value>

{

}

而boost::integral_const的定义在boost/type_traits/integral_constant.hpp很简单,其中mpl::true_在 boost/mpl/bool.hpp boost/mpl/bool_fwd.hpp 中定义 应该很容易看懂,就不罗嗦了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值