2013-07-24 15 views
11

Soweit ich weiß, bedeutet SFINAE Substitution Ausfälle führen nicht zu Kompilierungsfehlern, sondern nur den Prototyp aus der Liste der möglichen Überlastungen entfernen.Verständnis SFINAE

Was ich nicht verstehe: warum ist das SFINAE:

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

Aber das ist nicht wahr?

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

Aus meinem Verständnis ist die zugrunde liegende Logik hier identisch. Diese Frage ergab sich aus den Kommentaren zu this answer.

+5

Kein Code ist SFINAE. – jrok

+0

Sie scheinen Ihre eigene Frage zu beantworten: SFINAE _nicht_ einen Fehler bei der Kompilierung verursacht (wenn Substitution fehlschlägt), während der ganze Zweck einer statischen Behauptung _is_ einen Fehler bei der Kompilierung verursachen (ist eine Bedingung nicht wahr ist) –

+1

@ jrok Wikipedia sagt 'enable_if' ist SFINAE, ist es falsch? – nijansen

Antwort

12

in C++ 98 wird SFINAE getan entweder mit einem Rückgabetyp oder eine Dummy-Argumente der Funktion mit Standard-Parametern

// 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); 

In beiden Fällen substution von T, um den verschachtelten Typ type ist das zu bekommen Essenz von SFINAE. Im Gegensatz zu std::enable_if, Ihre assert Vorlage hat nicht eine verschachtelte Art, die in Substitutions Teil SFINAE verwendet werden können.

See Jonathan Wakely ausgezeichnete ACCU 2013 presentation für weitere Einzelheiten und auch für die C++ 11-Expression SFINAE. Unter anderem (wie @BartekBanachewicz in den Kommentaren darauf hingewiesen hat) ist es nun auch möglich, SFINAE in Funktionsschablonen-Standardargumenten zu verwenden

// 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

Sie können das auch in der Template-Argumentliste tun. –

+2

Also 'enable_if' ** ist nicht ** SFINAE, aber' typenname enable_if :: type ** ist ** SFINAE, weil es nicht zu einem Fehler führt, wenn die Template-Substitution fehlschlägt (solange es nicht die einzige ist Spiel)? – nijansen

+0

@nijansen richtig! – TemplateRex