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

Messaggio di errore:Perché SFINAE (enable_if) non funziona per le funzioni membro di un modello di classe?

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

Source sul cpp.sh. Ho pensato che entrambi typename std::enable_if<std::is_same<T,?>::value>::type non potevano essere validi allo stesso tempo.

Modifica

Ai posteri qui è la mia modifica sulla base di @ KerrekSB risposta - SFINAE funziona solo per gli argomenti di template dedotte

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

risposta

12

SFINAE funziona solo per dedurre argomenti di template, vale a dire per i modelli di funzione. Nel tuo caso, entrambi i modelli sono istanziati incondizionatamente e l'istanziazione fallisce.

La seguente variante così:

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

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

ora Foo()(x) cause al massimo uno dei sovraccarichi creare un'istanza, poiché sostituzione argomento non in tutti gli altri.

Se si vuole attaccare con la struttura originale, uso esplicito modello di classe di specializzazione:

template <typename> struct Foo; 

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

* SFINAE funziona solo per gli argomenti di template dedotte * ... Questa è la chiave !!!!! Grazie grappolo @Kerrek. A proposito, il mio post originale è MWE. – Olumide

+2

@Olumide: Sì, solo i guasti di sostituzione risultanti dalla detrazione non sono errori. Le sostituzioni richieste esplicitamente falliscono come un errore grave. (Un MFE è sufficiente per questo caso!) –

+0

C'è un modo di avere un costruttore sovraccarico come questo? – Brent