2015-06-20 16 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() 
    {} 
}; 

Komunikat o błędzie:Dlaczego funkcja SFINAE (enable_if) nie działa dla funkcji składowych szablonu klasy?

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()' 

Źródło na cpp.sh. Myślałem, że zarówno typename std::enable_if<std::is_same<T,?>::value>::type nie może być ważny w tym samym czasie.

Edit

Dla potomności tutaj jest moje edycji w oparciu o użytkownika @ KerrekSB odpowiedź - SFINAE działa tylko dla przewidywanych argumentów szablonu

#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() 
{ 
}; 

Odpowiedz

12

SFINAE tylko pracuje dla wyprowadzona argumenty szablonu, tj. dla szablonów funkcji. W twoim przypadku oba szablony są bezwarunkowo tworzone i instancja kończy się niepowodzeniem.

Poniższy wariant działa:

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

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

Teraz Foo()(x) przyczyny co najwyżej jeden z przeciążeniami być instancja, ponieważ zastąpienie argumentem nie we wszystkich pozostałych.

Jeśli chcesz trzymać się swojej pierwotnej struktury, użyj wyraźnej specjalizacji klasa Szablon:

template <typename> struct Foo; 

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

* SFINAE działa tylko dla przewidywanych argumentów szablonu * ... To jest klucz !!!!! Dzięki wiązka @Kerrek. BTW, mój oryginalny post to MWE. – Olumide

+2

@Olumide: Tak, tylko błędy zastąpienia, które wynikają z dedukcji, nie są błędami. Jawnie żądane zastępstwa zawodzą jako poważny błąd. (W tym przypadku wystarczy tylko MFE!). –

+0

Czy istnieje sposób na przeciążenie takiego konstruktora? – Brent

Powiązane problemy