C 模板之SFINAE技術

2021-07-25 02:40:30 字數 982 閱讀 7044

templatestruct has_no_destroy

;

有乙個模板類的成員函式呼叫了它:

static void init()

}

看起來很不明白為什麼。然後蒐集資料,學習到了c++模板除了萃取的又乙個新技術,sfinae技術,即匹配失敗不是錯誤。

sfinae的意思是這樣的,假如有乙個特化會導致編譯時錯誤(即出現編譯失敗),只要還有別的選擇可以被選擇,那麼就無視這個特化錯誤而去選擇另外的可選選擇。

舉例:在上面這個示例中,如果我們給傳的引數t型別為pod型別,當呼叫detail::has_no_destroy::value時,t引數會在has_no_destroy類中例項化模板,由於是pod型別,不具備no_destroy方法,不可以使用&c::no_destroy方式呼叫,意味這如果匹配這個會導致編譯錯誤,那麼它會尋找下乙個去例項化。不過因為test(...)的存在,任何不匹配上乙個的到這裡都會被接收,所以我們宣告出來的成員變數test會是int32_t型別,而不是char型別。則下一行的value,由於測量test零初始化的位元組數,相當於sizeof(int32_t) != 1,所以value的值被確定為false。

我們退出這個函式,回到呼叫處。if(!detail::has_no_destroy::value)此時if語句不成立,所以不用註冊atexit時的destroy函式。我們是以pod型別舉例的,pod型別不正好不需要destroy嗎?完美。

下面是乙個例子,同樣驗證了sfinae技術:

#include using namespace std;

template struct has_typedef_foobar ;

struct foo ;

int main()

{ cout<::value<::value《所以可以說,sfinae技術也可以用來檢測某個引數是否有某個方法。

參考:

啃模板技術之SFINAE

sfinae說直白點就是模板類和模板函式匹配替換,找候選時的取捨過程。模板的篩選確定一定是要找到最準確的那個,而恰恰c 又支援類模板的特化和函式過載,那面對多個同名的定義,怎麼辦?先找出所有候選,候選的意思是能用就用,不能用換別個。所以對挑選過程一視同仁,先做實參的型別替換,乙個不匹配就換下乙個。這...

模板之組合技術

1 模板可以遞迴呼叫 listli list lli list llli 2 如果需要特定的 組合型別 可以通過派生來定義它們。這是派生的一種不太常見的應用,因為這裡並不增加成員。這種派生的應用也不會造成任何時間或則空間上的開銷 template class list2 public list li...

C 模板之模板特化

1.模板特化概念 使用模板可以實現一些與型別無關的 但對於一些特殊型別的可能會得到一些錯誤的結 果。就需要對模板進行特化。即 在原模板類的基礎上,針對特殊型別所進行特殊化的實現方式。2.模板特化分類 必須要先有乙個基礎的函式模板 關鍵字template後面接一對空的尖括號 函式名後跟一對尖括號,尖括...