2015-06-20 7 views
8
#include <type_traits> 

struct A{}; 
struct B{}; 

template <typename T> 
struct Foo 
{ 
    typename std::enable_if<std::is_same<T, A>::value>::type 
    bar() 
    {} 

    typename std::enable_if<std::is_same<T, B>::value>::type 
    bar() 
    {} 
}; 

Fehlermeldung:Warum funktioniert SFINAE (enable_if) nicht für Elementfunktionen einer Klassenvorlage?

14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5: 
error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()' 

Quelle auf cpp.sh. Ich dachte beide typename std::enable_if<std::is_same<T,?>::value>::type konnte nicht gleichzeitig gültig sein.

bearbeiten

Für die Nachwelt hier ist meine bearbeiten basierend auf @ KerrekSB Antwort - SFINAE nur für abgeleitete Vorlage Argumente arbeitet

#include <type_traits> 

struct A{}; 
struct B{}; 

template<typename T> 
struct Foo 
{ 
    template<typename U = T> 
    typename std::enable_if<std::is_same<U,A>::value>::type 
    bar() 
    { 
    } 

    template<typename U = T> 
    typename std::enable_if<std::is_same<U,B>::value>::type 
    bar() 
    { 
    } 
}; 

int main() 
{ 
}; 

Antwort

12

SFINAE funktioniert nur für Vorlage Argumente abgeleitet, zB für Funktionsvorlagen. In Ihrem Fall werden beide Vorlagen unbedingt instanziiert, und die Instanziierung schlägt fehl.

Die folgende Variante funktioniert:

struct Foo 
{ 
    template <typename T> 
    typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {} 

    // ... (further similar overloads) ... 
}; 

Jetzt Foo()(x) Ursachen höchstens einer der Überlastungen instanziiert werden, da Argument Substitution in all den anderen ausfällt.

Wenn Sie mit Ihrem ursprünglichen Struktur bleiben möchten, verwenden Sie explizite Klasse Template-Spezialisierung:

template <typename> struct Foo; 

template <> struct Foo<A> { void bar() {} }; 
template <> struct Foo<B> { void bar() {} }; 
+1

* SFINAE funktioniert nur für die abgeleitete Vorlage Argumente * ... Das ist der Schlüssel !!!!! Danke Haufen @Kerrek. BTW, mein ursprünglicher Posten ist MWE. – Olumide

+2

@Olumide: Ja, nur Substitutionsfehler, die sich aus dem Abzug ergeben, sind keine Fehler. Explizit angeforderte Substitutionen schlagen als ein schwerer Fehler fehl. (Ein MFE reicht für diesen Fall!) –

+0

Gibt es eine Möglichkeit, einen überladenen Konstruktor so zu haben? – Brent