2015-12-19 19 views
6

Quindi, sto seguendo l'esempio del codice da qualche parte in questa pagina web: http://eli.thegreenplace.net/2014/sfinae-and-enable_if/SFINAE: std :: enable_if come argomento di funzione

Ecco quello che ho:

template<typename T> 
void fun(const typename std::enable_if_t<std::is_integral<T>::value, T>& val) { 
    std::cout << "fun<int>"; 
} 

template<typename T> 
void fun(const typename std::enable_if_t<std::is_floating_point<T>::value, T>& val) { 
    std::cout << "fun<float>"; 
} 

int main() 
{ 
    fun(4); 
    fun(4.4); 
} 

In questo modo Dovrei scrivere:

fun<int>(4); 
fun<double>(4.4); 

Come evitarlo?

Il compilatore si lamenta di non poter dedurre il parametro T.

risposta

5

Gli esempi sono errati, poiché Tè in un non-deduced context. A meno che non si chiami la funzione come fun<int>(4);, il codice non verrà compilato, ma probabilmente non è ciò che l'autore intendeva mostrare.

L'utilizzo corretto sarebbe quello di consentire T da dedurre dal compilatore e di posizionare una condizione SFINAE altrove, ad es. in un tipo di ritorno sintassi:

template <typename T> 
auto fun(const T& val) 
    -> typename std::enable_if<std::is_integral<T>::value>::type 
{ 
    std::cout << "fun<int>"; 
} 

template <typename T> 
auto fun(const T& val) 
    -> typename std::enable_if<std::is_floating_point<T>::value>::type 
{ 
    std::cout << "fun<float>"; 
} 

DEMO

Inoltre, le typename s nel codice contraddicono l'uso di std::enable_if_t.

Utilizzare uno (C++ 11):

typename std::enable_if<...>::type 

o (C++ 14):

std::enable_if_t<...> 

Come sarebbe che il lavoro in un costruttore che doesn 't avere un tipo di ritorno però?

In caso di costruttori, la condizione SFINAE può essere nascosto in una lista di parametri modello:

struct A 
{  
    template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> 
    A(const T& val) 
    { 
     std::cout << "A<int>"; 
    } 

    template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0> 
    A(const T& val) 
    { 
     std::cout << "A<float>"; 
    } 
}; 

DEMO 2

+0

Vedo. Come funzionerebbe in un costruttore che non ha un tipo di ritorno? – DeiDei

+0

@DeiDei vedere l'aggiornamento –

+0

Qual è il significato dell'uso di 'int' come secondo argomento di' std :: enable_if'? È arbitrario? O perché 'int = 0' è sicuro? – Jacob

1

Per consentire la deduzione è necessario un parametro di funzione che è semplicemente basato sulla T . È quindi necessario capire dove mettere il tuo enable_if (che in effetti non consente di dedurre T). Le opzioni comuni sono sul tipo restituito o su un parametro predefinito extra che si ignora.

Alcuni buoni esempi: http://en.cppreference.com/w/cpp/types/enable_if

Problemi correlati