Auswählen einer Mitgliedsfunktion mithilfe von Enable_If-Bedingungen
Die Aufgabe besteht darin, den Aufruf einer Mitgliedsfunktion basierend auf einem Klassenvorlagenparameter zu bestimmen. Das folgende Code-Snippet versucht, dies zu erreichen:
<code class="cpp">#include <iostream> #include <type_traits> template<typename T> struct Point { void MyFunction(typename std::enable_if<std::is_same<T, int>::value, T &>::type* = 0) { std::cout << "T is int." << std::endl; } void MyFunction(typename std::enable_if<!std::is_same<T, int>::value, float &>::type* = 0) { std::cout << "T is not int." << std::endl; } };</code>
Dieser Code kann jedoch nicht kompiliert werden, und es wird der Fehler „kein Typ namens ‚type‘ in ‚struct std::enable_if‘“ angezeigt.
SFINAE in Aktion
Der Schlüssel zum Verständnis dieses Problems liegt im Konzept von Substitution Failure Is Not An Error (SFINAE). Enable_if ermöglicht die bedingte Kompilierung basierend auf Vorlagenargumenten. In diesem Fall ist das Vorlagenargument T bereits bekannt, wenn die Memberfunktionen instanziiert werden. Daher wird die Bedingung zum Zeitpunkt der Instanziierung ausgewertet und die entsprechende Funktion ausgewählt.
Korrektur des Codes
Um dies zu beheben, müssen wir ein Dummy-Vorlagenargument einführen ist standardmäßig auf T eingestellt. Dadurch kann der SFINAE-Mechanismus wie vorgesehen funktionieren. Der geänderte Code würde wie folgt aussehen:
<code class="cpp">template<typename T> struct Point { template<typename U = T> typename std::enable_if<std::is_same<U, int>::value>::type MyFunction() { std::cout << "T is int." << std::endl; } template<typename U = T> typename std::enable_if<std::is_same<U, float>::value>::type MyFunction() { std::cout << "T is not int." << std::endl; } };</code>
Explizite Member-Funktionsspezialisierung verhindern
Wie von HostileFork hervorgehoben, ermöglicht der Originalcode die explizite Angabe von Vorlagenargumenten für die Mitgliedsfunktionen, was zu falschen Ergebnissen führen könnte. Um dies zu verhindern, können wir ein static_assert hinzufügen, das prüft, ob Vorlagenargumente bereitgestellt werden. Dadurch wird sichergestellt, dass immer die richtige Memberfunktion basierend auf dem Vorlagenargument T aufgerufen wird. Der geänderte Code wäre:
<code class="cpp">template<typename T> struct Point { template<typename... Dummy, typename U = T> typename std::enable_if<std::is_same<U, int>::value>::type MyFunction() { static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!"); std::cout << "T is int." << std::endl; } template<typename... Dummy, typename U = T> typename std::enable_if<std::is_same<U, float>::value>::type MyFunction() { static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!"); std::cout << "T is not int." << std::endl; } };</code>
Das obige ist der detaillierte Inhalt vonWie wähle ich eine Mitgliedsfunktion basierend auf einem Vorlagenparameter mit „enable_if' aus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!