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後面接一對空的尖括號 函式名後跟一對尖括號,尖括...