Heim  >  Artikel  >  Backend-Entwicklung  >  Wie wähle ich eine Mitgliedsfunktion basierend auf einem Vorlagenparameter mit „enable_if“ aus?

Wie wähle ich eine Mitgliedsfunktion basierend auf einem Vorlagenparameter mit „enable_if“ aus?

DDD
DDDOriginal
2024-10-25 19:06:39763Durchsuche

How to Select a Member Function Based on a Template Parameter Using `enable_if`?

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn