Heim  >  Artikel  >  Backend-Entwicklung  >  Warum schlägt SFINAE für Klassenvorlagen-Memberfunktionen fehl?

Warum schlägt SFINAE für Klassenvorlagen-Memberfunktionen fehl?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-04 22:18:02743Durchsuche

Why Does SFINAE Fail for Class Template Member Functions?

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:

  • Funktionsvorlagen verwenden: Definieren Sie separate Funktionsvorlagen für jede Überladung, wie unten gezeigt:
<code class="cpp">template <typename T>
void bar(Foo<T><- A) {}

template <typename T>
void bar(Foo<T><- B) {}
  • Explizite Klassenvorlagenspezialisierung verwenden: Separate definieren Klassenvorlagen für jede Überladung, wie unten gezeigt:
<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!

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