C++/元函數
< C++
元函數
編輯
定義
編輯元函數(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;
};
用例
編輯參考文獻
編輯A Deeper Look at Metafunctions -- David Abrahams and Aleksey Gurtovoy