C 慣用法 metafunction(元函式)

2021-05-22 02:21:53 字數 2004 閱讀 4109

與執行期使用函式封裝演算法相對應,在c++編譯期同樣存在著封裝演算法進行編譯期計算的需要。元函式(metafunction)便是實現這一需求的主要手段。元函式這一概念最早是由boost.mpl類庫提出並定義的。

作為在編譯期進行計算的函式,元函式具有以下不同於執行期函式的特點:

輸入(即引數)與輸出(即返回值)均只包含兩種型別:1)型別(名)2)整形常量。

可以返回乙個或多個值,但不能沒有返回值。

沒有***:元函式在計算過程中既不能改變引數的值,也不具備「向控制台輸入輸出」之類的附加功能。

按照返回值的型別來劃分,元函式可分為以下兩大類:

type型元函式:返回型別(名)的元函式,也就是在編譯期進行型別計算的元函式。

示例**1:示例**1定義了乙個用於編譯期型別選擇的元函式if,其實現依賴於類模板if及其特化。

元函式if的輸入由3個模板引數構成:布林型別b,型別名l,型別名r。

元函式if的輸出也就是需要返回的型別由typedef語句來定義,用於返回的型別名為type。

此處用於返回的型別名取名為type是為了遵循boost.mpl類庫的慣例。

若b的值為true,則元函式if返回型別名l。(此分支由模板特化來定義)

若b的值為false,則元函式if返回型別名r。(此分支由主模板來定義)

此處用struct關鍵字而不是class關鍵字來定義類模板的理由是:元函式if的返回型別必須能被外界所訪問,即type的訪問許可權必須是public。

value型元函式:返回整形常量的元函式,也就是在編譯期進行常量計算的元函式。

示例**2:示例**2定義了乙個用於編譯期計算階乘的元函式factorial,其實現依賴於類模板factorial及其特化。

元函式factorial的輸入僅由1個模板引數構成:整數型別n。

元函式factorial的輸出也就是需要返回的整形常量由列舉或靜態整形常量來定義,用於返回的常量名為value。

此處用於返回的常量名取名為value是為了遵循boost.mpl類庫的慣例。

若n的值為0,則元函式factorial返回1。(此分支由模板特化來定義)

若n的值大於0,則元函式factorial返回n*factorial(n-1)。(此分支由主模板來定義)

此處用struct關鍵字而不是class關鍵字來定義類模板的理由是:元函式factorial的返回值必須能被外界所訪問,即value的訪問許可權必須是public。

與執行期的函式有所不同,編譯期所定義的元函式也可返回不止乙個值。

示例**3:示例**3(取自boost.mpl類庫)實現了乙個布林常量的包裝器。

元函式bool_共有3個返回值。

1) 布林值value。

2) 元函式自身的型別type。

3) 布林值value的型別value_type。

根據元函式bool_的定義,不難推出以下等式為真。

1) false_::value == false。

2) true_::type::value == true。

元函式也可不用類模板而用普通的類來定義,此時元函式的引數個數為0,即元函式沒有輸入只有輸出。

示例**4:

元函式也可在類或類模板中定義,即元函式通過巢狀類的方式來實現。

這種元函式可稱作「成員」元函式,也可稱作「元方法」。

示例**5:在示例**5(取自boost.pheonix類庫)中,類模板value總共定義了2個元方法。

1) value型元方法no_nullary。

這裡no_nullary被定義為false_的同義詞,false_的定義可參見示例**3。

2) type型元方法result。

元函式的引數也可以是另乙個元函式,這種元函式被稱作高階元函式。boost.mpl類庫中的transform就屬於高階元函式。

編譯期「元函式」

執行期「函式」

是否允許返回多值是否

是否允許不返回值否是

是否存在***否是

是否允許零引數是是

能否作為類成員是是

是否存在高階函式是是

C 之RAII慣用法

c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 在資...

C 之RAII慣用法

c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 cp...

C 之RAII慣用法

c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 vo...