boost::function_types提供了对函数签名、函数指针、函数引用和成员指针等类型进行分类、分解和合成的功能。而这些类型统称为可调用内建类型(callable builtin types)。

tag标签的说明

头文件:#include <boost/function_types/property_tags.hpp>

tag类型:

template<class Tag1, class Tag2, class Tag3 = null_tag, class Tag4 = null_tag>
struct tag;

#include #include

namespace func_types = boost::function_types;

int main() { cout << func_types::is_function::value << endl; // 输出为1

return 0;

}


 
* 复合的属性 tag 描述了不同属性的可能值的组合。
    1. 类型 `components<F>`, 其中 F 为可调用内建类型,是描述 F 的复合属性 tag。类模板 tag 可用于合成属性 tags。如:`tag<non_const,default_cc> // 两个属性的组合`
    2. 当同一个属性的多个值在 tag 的参数列表中被指定时,只使用最右边的一个;其它值会被忽略。`tag<components<F>, default_cc> // 覆盖 F 的调用协定属性`
 
* 当复合属性 tag 被指定为分析一个类型,它的所有组成属性都必须匹配。
```c++
is_member_function_pointer<F, tag<const_qualified,default_cc>>::value
// true for
//   F = void(a_class::*)() const
 
// false for
//   F = void(a_class::*)()                     // 非const
//   F = void(__fastcall a_class::*)() const    // 非默认调用协stdcall

各个tag标识:

variadic
表示函数类型通过一个省略号参数接受变长数量的参数(例如 printf)。

non_variadic
表示函数类型不带省略号参数。

default_cc
表示函数类型按缺省的调用协定进行编码。

const_qualified
表示函数类型是 const 限定的。

non_const
表示函数类型不是 const 限定的。

volatile_qualified
表示函数类型是 volatile 限定的。

non_volatile
表示函数类型不是 volatile 限定的。

non_cv
表示函数类型既不是 const 限定也不是 volatile 限定的。
等价于 tag<non_const,non_volatile>, 不过在求值时执行更少的模板实例化。

const_non_volatile
表示函数类型是 const 限定但非 volatile 限定的。

volatile_non_const
表示函数类型是 volatile 限定但非 const 限定的。

cv_qualfied
表示函数类型同时是 const 和 volatile 限定的。
等价于tag<const_qualified,volatile_qualified>, 不过在求值时执行更少的模板实例化。

null_tag
表示没有标签。

分析、构造可调用内建类型的traits

每个traits类型都有个与类型名同名的头文件。

用于类型分类的类模板

取出一个可调用内建类型的所有属性,即结果类型及参数类型(对于成员函数指针还包括 this 的类型)。
components<T,ClassTransform>::types 输出对应的序列mpl::vector<>

#include <iostream>
#include <typeinfo>
using namespace std;
 
#include <boost/function_types/property_tags.hpp>
#include <boost/function_types/components.hpp>
#include <boost/type_traits.hpp>
 
namespace func_types = boost::function_types;
 
typedef int (*func)( int, string );
 
class Test {};
 
int main()
{
    // mpl::vector3<int,int,string>
    cout << typeid( func_types::components<func>::types ).name() << endl;
 
    // mpl::vector3<void,Test const&,double>
    cout << typeid( func_types::components< void (Test::*) ( double ), boost::add_reference< boost::add_const< boost::mpl::_ > > >::types ).name() << endl;
    return 0;
}

用于类型合成的类模板

根据给定的属性合成一个成员函数指针。
序列中的第二个类型如果带有引用或 cv-限定的指针,则会被去除,以确定类的类型。结果类型的 cv-限定被应用于成员函数,除非另外通过属性标签进行显式指定。

例子:

#include <iostream>
#include <typeinfo>
using namespace std;
 
#include <boost/function_types/property_tags.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/function_reference.hpp>
#include <boost/function_types/member_function_pointer.hpp>
#include <boost/mpl/vector.hpp>
 
namespace func_types = boost::function_types;
 
typedef int (*func)( int, string );
class Test{};
 
int main()
{
    //从mpl::vector<>序列或其他可调用内建类型得到 函数签名
    cout << typeid( func_types::function_type< boost::mpl::vector<int,string,double> >::type ).name() << endl;
    cout << typeid( func_types::function_type< int (Test::*)(double) >::type ).name() << endl;
   
    //从已有的函数指针类型得到对应的函数类型
    cout << typeid( func_types::function_pointer< func >::type ).name() << endl;
    cout << typeid( func_types::function_reference< func >::type ).name() << endl;
 
    // 得到成员函数指针( 类型复制 或者 mpl序列 )
    cout << typeid( func_types::member_function_pointer< int (Test::*)(double)const >::type ).name() << endl;
 
    // 显式加上const
    cout << typeid( func_types::member_function_pointer< boost::mpl::vector<int,Test,double>, func_types::const_qualified >::type ).name() << endl;
 
    // const保留到了成员函数
    cout << typeid( func_types::member_function_pointer< boost::mpl::vector<int,Test const&,double> >::type ).name() << endl;
 
 
    return 0;
}

// 输出:
// int __cdecl(string,double)
// int __cdecl(class Test &,double)
// int (__cdecl*)(int,string)
// int __cdecl(int,string)
// int (__thiscall Test::*)(double)const
// int (__thiscall Test::*)(double)const
// int (__thiscall Test::*)(double)const