2017-07-14 3 views
1

Ich bin neu bei SFINAE. Ich habe bemerkt, dass:Vorlage Abzug mit SFINAE in C++

template <typename T> void f(T t) { t.Crash(); } // version 1 
void f(...) { } // The sink. 
f(1); 

template <typename T> void f(const T& t, typename T::iterator* it = nullptr) { } // version 2 
void f(...) { } // The sink. 
f(1); 

in Version 2, wegen SFINAE, es sind keine Störungen werfen, und wählen Sie die Ellipse Waschbecken. aber warum bei Version 1 wird der Compiler stoppen und sich beschweren?

Gilt die SFINAE nur für die Unterschrift und nicht für den Körper? in Version 1 bevorzugt es die Template-Funktion, aber in welchem ​​Stadium stoppt der Compiler und wirft einen Fehler?

Bitte erläutern Sie explizit die Verarbeitungsstufen des Compilers in Bezug auf die Vorlage Überladungsauflösung.

Antwort

4

aber warum in Version 1 wird der Compiler stoppen und beschweren?

template <typename T> void f(T t) { t.Crash(); } // version 1 
void f(...) { } // The sink. 
f(1); 

Es gibt keine eine Substitution Fehler in der Templat-Version von f oben, weil T als int aus dem Aufruf f(1) abgeleitet werden. Und nach der Überladungsauflösung Regeln wird die f<int>(int) mehr bevorzugt als f(...)


template <typename T> void f(const T& t, typename T::iterator* it = nullptr) { } // version 2 
void f(...) { } // The sink. 
f(1); 

Es gibt eine Substitution Versagen gibt, da wird der Compiler müssen die Art der it nach T als int herzuleiten abzuleiten. Es ersetzt int anstelle von int::iterator, was ungültig ist.


SFINAE auf Funktionen arbeitet im Rahmen der Erstellung gültigen funktions Template-Spezialisierung.

Gilt die SFINAE nur für die Signatur und nicht für die Körper?

können Sie so etwas sagen ... bei diesen gültigen Code-Beispiele eine Beute nehmen:

//Just the declaration 
template <typename T> 
void f(T t); 

void f(...); 

int main(){ 
    f(1); //selects f<int>(int) 
} 

Zwischenzeit:

//just the declarations. 
template <typename T> 
void f(const T& t, typename T::iterator* it = nullptr); 

void f(...); 

int main(){ 
    f(1); //selects f(...) 
}