SFINAE in Rückgabetypen vs. Vorlagenparametern
Angenommen, wir haben eine Funktionsvorlage foo, die zwischen Ganzzahl- und Gleitkommazahlen unterscheidet:
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> auto foo(T) -> void; template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type> auto foo(T) -> void;
Dieser Code schlägt jedoch mit einem Fehler fehl, wenn er mit einem Double aufgerufen wird Wert:
foo(3.4); // Error: no matching function for call to 'foo(double)'
Warum schlägt dieser Ansatz fehl?
In diesem Fall wird SFINAE verwendet, um den Rückgabetyp von foo bedingt zu definieren. Dies verstößt jedoch gegen die Regeln zum Überladen von Funktionsvorlagen, die keine Standardvorlagenargumente berücksichtigen. Folglich behandelt der Compiler beide foo-Vorlagen als dieselbe Funktion mit derselben Signatur.
Alternativer Ansatz mit ausdrucksverweisenden Vorlagenparametern
Um dieses Problem zu beheben, können wir stattdessen Folgendes tun Verwenden Sie ausdrucksverweisende Vorlagenparameter im Rückgabetyp:
template<typename T> auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type; template<typename T> auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type;
Mit dieser Änderung wird der Ausdruck std::enable_if Teil von Funktionssignatur, die es SFINAE ermöglicht, zwischen den beiden foo-Vorlagen zu unterscheiden.
Daher funktioniert die zweite Version von foo korrekt, während die erste Version einen Fehler auslöst.
Das obige ist der detaillierte Inhalt vonWarum schlägt SFINAE bei Rückgabetypen fehl, bei Vorlagenparametern jedoch erfolgreich?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!