SFINAE schlägt für Klassenvorlagen-Memberfunktionen fehl
Der SFINAE-Mechanismus (Substitute Failure, Is Not An Error), der häufig bei der Metaprogrammierung von Vorlagen verwendet wird, scheint ein eigenartiges Verhalten zu zeigen, wenn es auf Klassenvorlagen-Memberfunktionen angewendet wird.
Das Problem
Betrachten Sie den folgenden Codeausschnitt:
<code class="cpp">#include <type_traits> struct A{}; struct B{}; template <typename T> struct Foo { // Conditional enable bar() for T == A typename std::enable_if<std::is_same<T, A>::value>::type bar() {} // Conditional enable bar() for T == B typename std::enable_if<std::is_same<T, B>::value>::type bar() {} };</code>
Dieser Code versucht, zwei Überladungen von bar() in der Foo-Klassenvorlage zu definieren, wobei SFINAE verwendet wird, um jede Überladung basierend auf dem Wert von T bedingt zu aktivieren. Der Code kann jedoch nicht mit dem folgenden Fehler kompiliert werden:
<code class="cpp">error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded</code>
Die Erklärung
SFINAE wird normalerweise verwendet, um Vorlagenspezialisierungen basierend auf Vorlagenargumenten zu aktivieren oder zu deaktivieren. SFINAE gilt jedoch nur für abgeleitete Vorlagenargumente, d. h. Argumente, die bei der Überlastungsauflösung automatisch abgeleitet werden. Bei Memberfunktionen werden Vorlagenargumente nicht abgeleitet, sondern beim Instanziieren der Klasse explizit angegeben. Daher ist SFINAE nicht auf Mitgliedsfunktionen anwendbar.
Die Lösung
Es gibt zwei Hauptmöglichkeiten, dieses Problem anzugehen:
<code class="cpp">template <typename T> void bar(Foo<T><- A) {} template <typename T> void bar(Foo<T><- B) {}
<code class="cpp">template <typename> struct Foo; template <> struct Foo<A> { void bar() {} }; template <> struct Foo<B> { void bar() {} };</code>
Das obige ist der detaillierte Inhalt vonWarum schlägt SFINAE für Klassenvorlagen-Memberfunktionen fehl?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!