2013-07-24 35 views
11

據我所知,SFINAE意味着替換失敗不會導致編譯錯誤,但只是從可能的重載列表中刪除原型。瞭解SFINAE

我不明白:這是爲什麼SFINAE:

template <bool C, typename T = void> struct enable_if{}; 
template <typename T> struct enable_if<true, T> { typedef T type; }; 

但這不是?

template <bool C> struct assert; 
template <> struct assert<true>{}; 

從我的理解,這裏的基本邏輯是相同的。這個問題從this answer的評論中浮現出來。

+5

既不代碼SFINAE使用SFINAE。 – jrok

+0

您似乎回答了您自己的問題:SFINAE不會導致編譯時錯誤(如果替換失敗),而靜態斷言的整個目的是導致編譯時錯誤(某些情況並非如此) –

+1

@ jrok維基百科說'enable_if'是SFINAE,它錯了嗎? – nijansen

回答

12

在C++ 98,SFINAE若非由返回類型或函數的默認參數

// SFINAE on return type for functions with fixed arguments (e.g. operator overloading) 
template<class T> 
typename std::enable_if< std::is_integral<T>::value, void>::type 
my_function(T const&); 

// SFINAE on dummy argument with default parameter for functions with no return type (e.g. constructors) 
template<class T> 
void my_function(T const&, std::enable_if< std::is_integral<T>::value, void>::type* = nullptr); 

僞參數在這兩種情況下,爲了得到嵌套式type是做的T替換操作SFINAE的本質。與std::enable_if相反,您的assert模板沒有可用於SFINAE的替代部分的嵌套類型

請參閱Jonathan Wakely的優秀ACCU 2013 presentation以瞭解更多細節以及C++ 11表達式SFINAE。等(如在評論中指出的@BartekBanachewicz)是現在也可以在函數模板默認參數

// use C++11 default function arguments, no clutter in function's signature! 
template<class T, class dummy = typename std::enable_if< std::is_integral<T>::value, void>::type> 
void my_function(T const&); 
+0

你也可以在模板參數列表中做到這一點。 –

+2

所以'enable_if' **不是** SFINAE,但'typename enable_if :: type' **是** SFINAE,因爲如果模板替換失敗,它不會導致錯誤(只要它不是唯一的比賽)? – nijansen

+0

@nijansen正確! – TemplateRex