2010-10-21 37 views
9

我感到困惑使用的優勢:: MPL :: bool_,而不是一個常量布爾

bool_<true> 

bool_<false> 

類型反對簡單地使用const的布爾變量的優勢模板元編程的上下文。

boost :: mpl庫顯然更喜歡第一種方法,並且定義了像and_,or_這樣的幫助函數來幫助管理這種bool_。像if_這樣的條件元函數「取」一個bool_作爲第一個(模板)參數,但在後臺「調用」一個if_c元函數,這個函數需要一個(const)布爾作爲第一個(模板)參數。

這個決定背後的理由是什麼?

非常感謝您的幫助!

回答

11

這裏是一個簡短的例子,我是如何每時每刻都使用這些類型的。本實施例中是不可能的,使用常量布爾:

void do_something(boost::mpl::bool_<true>) 
{ 
    ... 
} 

void do_something(boost::mpl::bool_<false>) 
{ 
    ... 
} 

呼叫的根據參數的類型這兩種功能中的一個:

template<class T> 
void doIt(void) 
{ 
    do_something(boost::mpl::bool_<boost::is_pointer<T>::val>()) 
} 

在這種情況下,第一或第二函數將稱爲,取決於事實如果類型T是否是一個指針。這些類型允許你使用函數重載,在那裏不可能使用const布爾。使用const布爾,你將不得不在運行時決定採用哪個分支。如果被調用的函數本身是模板,如果它們被實例化爲除預期之外的類型,則它們將不能正確編譯,這一點特別重要。上面的第一個函數定義可能包含只編譯指針的代碼。

+0

謝謝,這是一個很好的例子! – stepelu 2010-10-21 13:31:35

+0

哦,是的,我忘了重載! – sbi 2010-10-21 13:59:46

+2

這是一個很好的答案,但它比必要的更冗長得多。你可以寫'do_something(boost :: is_pointer ())',它將以幾乎相同的方式完成同樣的事情。 – 2011-11-28 16:46:36

2

我想一個原因是,bool_<...>的類型和使用它們作爲元函數的結果的時候,你就永遠沒有停下來想一想你的結果是否是一個類型,你所要做的

typedef some_type result; 

或必須返回的值

const static ??? result = some_value; 

您還必須跟蹤其類型。

而且,我懷疑(我還沒有Boost.MPL工作還),他們都有一個result型嵌套指的是自己,這樣你可以從他們剛剛獲得寫元功能:

template< bool b > 
struct my_meta_func : bool_<b> {}; 

並且可以調用my_meta_func::result

+0

你是對的,只是結果往往被稱之爲':: type'在MPL。 – 2011-11-28 16:47:45

8

這是關於創建足夠的統一性,圖書館可以提供有用的功能。 MPL協議是:「所有的元函數參數(和返回值)都是類型。」這使我們可以編寫一個可以在元功能上運行的模板。例如,該模板接受任何元函數(或者在C++ 03與多達N個參數中的任何元函數):

template <template <class...> class some_metafunction> 
struct wrapper; 

一旦允許一些模板參數是非類型,寫這樣的包裝變得不可能。對於我們關心的一個實際例子,這種一致性使得圖書館能夠區分和評估MPL lambda表達式。如果元函數參數被允許爲非特殊類型,該特徵將無法實現,因爲沒有辦法寫出所有需要的外部模板xxx與其參數aixxx<a1,a2,a3,...>解開所需的部分特殊化。

一個不那麼有趣的部分原因是很多東西變得不像我們在MPL中做的那樣冗長。比較:

and_<mf0<x,y>, mf1<z>, mf2<x,z> >::value 

VS

mf0<x,y>::value && mf1<z>::value && mf2<x,z>::value