2013-08-30 56 views
1
template<class T> 
struct is_class_or_union 
{ 
    struct twochar { char _[2]; }; 
    template <class U> 
    static char is_class_or_union_tester(void(U::*)(void)); 
    template <class U> 
    static twochar is_class_or_union_tester(...); 
    static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); 
}; 

上述代碼來自boost庫的meta_utils.hppBoost代碼摘錄 - 無法理解

  1. is_class_or_union_tester似乎是一個static函數返回char並採取指針成員函數(返回void並接受無)。沒有功能體,它似乎沒有在其他地方定義。我不明白它是如何工作的,而且最重要的是,我不明白該功能的用途。
  2. 我不明白以下代碼的概念: static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); sizeof運算符應用於什麼?他們想在這裏找到什麼?
+0

[C++ SFINAE示例?]的可能的重複(http://stackoverflow.com/questions/982808/c-sfinae-examples) – soon

+0

@peter感謝您的解釋。它當然有幫助。我不知道沒有鏈接器錯誤(對於函數定義),因爲該函數從未被調用? –

+0

沒有鏈接器錯誤,因爲實際上沒有創建代碼。 'sizeof'實際上並不執行它傳遞的表達式,而是計算出結果的類型,然後計算它的大小。 –

回答

3

這裏採用的技術是SFINAE(替換失敗不是錯誤),這是編譯器用來選擇可能的候選模板之間的匹配的一種技術,特別是在模板參數的無效替換本身不在其中在匹配過程中出現錯誤。在這種情況下,編譯器試圖找到一個匹配:

is_class_or_union_tester<T>(0) 

它可以選擇

template <class U> 
static char is_class_or_union_tester(void(U::*)(void)); 

template <class U> 
static twochar is_class_or_union_tester(...); 

之間。如果T是一個類會選擇第一個功能因爲一個類可以有一個成員函數。如果T是工會,它將選擇第二個。回想一下,sizeof不會執行這些函數,只會對模板聲明中的返回類型起作用。你會看到返回類型是不同的,這使得與sizeof(char)的比較返回正確的值。

+0

讓我想知道,如果語言允許並且人們使用這種機制,那麼應該設計一個明確的方法來實現這一點。這看起來非常非常黑客。 – szpanczyk