元函数
编辑

定义 编辑

元函数(metafunction)在编译时利用类模板,输入参数为类型或者编译期常量(一般要求为整型),返回类型或常量。 注意这一定义不包含constexpr函数。

元函数这一概念最早是由Boost.MPL类库提出并定义的。

作为在编译期进行计算的函数,元函数具有以下不同于运行期函数的特点:

  • 输入(即参数)与输出(即返回值)均只包含两种类型:1)类型(名)2)整形常量。
  • 可以返回一个或多个值,但不能没有返回值。
  • 没有副作用:元函数在计算过程中既不能改变参数的值,也不具备“向控制台输入输出”之类的附加功能。

动机 编辑

元函数的实现 编辑

元函数是用类模板实现,并常使用模板特化技术。

分类 编辑

按照返回值的类型来划分,元函数可分为以下两大类:

type型元函数:返回类型(名)的元函数,也就是在编译期进行类型计算的元函数。例如,下述IF类模板,根据第一个模板参数的值,返回第二个或第三个模板参数。这类似于运行时的if语句:

template <bool, class L, class R>
struct IF
{
  typedef R type; 
};

template <class L, class R>
struct IF<true, L, R>
{
  typedef L type; 
};

IF<false, int, long>::type i; // is equivalent to long i;
IF<true,  int, long>::type i; // is equivalent to int i;

value型元函数:返回整形常量的元函数,也就是在编译期进行常量计算的元函数。例如,Factorial元函数是递归计算阶乘,返回的最终结果为常量(应该是静态数据成员或者枚举类型的值):

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};
 
template <>
struct Factorial<0> 
{
    enum { value = 1 };
};
 
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}


与运行期的函数有所不同,编译期所定义的元函数也可返回不止一个值。即"Multiple returns"(返回多值的元函数)。例如,Boost.MPL类库中的Integral Constant Wrapper(整形常量包装器)就属于这种返回多个类型名及整形常量的元函数:

    template< bool x > struct bool_
    {
        static bool const value = x;        
        typedef bool_<x> type;              
        typedef bool value_type;            
        operator bool() const { return x; } 
    };
     
    typedef bool_<false> false_;
    typedef bool_<true> true_;

元函数也可不用类模板而用普通的类来定义,此时元函数的参数个数为0,即元函数没有输入只有输出。即Nullary Metafunction(零参数元函数)。例如:

    struct always_int
    {
        typedef int type;
    };

用例 编辑

Boost.MPL

参考文献 编辑

A Deeper Look at Metafunctions -- David Abrahams and Aleksey Gurtovoy