更多 C++ 习语/元函数
- 封装复杂的类型计算算法
- 使用编译时类型选择技术生成类型
模板是 C++ 的一个强大功能,它可以用于在编译时执行任意计算,这被称为模板元编程。编译时执行的一些基本计算示例包括:(1)根据编译时常量选择类型,或(2)计算数字的阶乘。事实上,C++ 模板是 C++ 的图灵完备子语言。元函数习语是编写 C++ 编译时算法的主要方式。
算法 - 编译时或运行时 - 应该被封装,以使其更容易使用和重用。按照惯例,运行时算法被封装在函数中,这些函数在运行时被调用。另一方面,元函数是运行时函数的编译时模拟。传统的函数接受值/对象作为参数并返回值/对象。但是,元函数接受类型和编译时常量作为参数并返回类型/常量。
元函数,与其名称相反,是一个类模板。元函数的实现通常基于模板特化。例如,考虑以下IF元函数,它是运行时if语句的编译时等效项。根据第一个参数的值,IF元函数在下面的示例中产生一个int或一个long。
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;
下面的Factorial元函数是另一个示例,展示了如何使用 C++ 模板封装递归阶乘计算算法。此元函数产生一个整数值,而不是一个类型。
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
}
元函数和类型生成器
元函数比类型生成器习语更通用的习语。元函数习语的目的是封装编译时计算,而类型生成器简化了类型的规范。生成类型作为编译时计算结果的元函数是类型生成器,但并非所有元函数都是类型生成器。例如,之前显示的Factorial元函数产生一个整数值,而不是一个类型。元函数通常使用编译时控制结构或其他元函数来实现。
诸如Boost.MPL之类的库提供大量元函数和编译时数据结构,以简化 C++ 模板元编程。
高阶元函数
这些是接受其他元函数作为参数并在计算期间使用它们的元函数。这在概念上类似于在运行时接受指向另一个函数的指针或函数对象的函数。唯一的区别是元函数只存在于编译时。boost::mpl::transform是这种高阶元函数的一个例子。
深入了解元函数 - David Abrahams 和 Aleksey Gurtovoy