2011-10-15 14 views
9

Ho cercato di realizzare uno SFINAE utilizza bool (a differenza popolare void_trick):SFINAE provato con bool dà errore del compilatore: "argomento template 'T :: valore' comporta parametro di modello"

template<typename T, bool = true> 
    struct Resolve 
    { 
    static const bool value = false; 
    }; 

    template<typename T> 
    struct Resolve<T, T::my_value> 
    { 
    static const bool value = true; 
    }; 

L'obiettivo è quello di specialize, le classi che hanno definito static const bool my_value = true; al suo interno. Se sono definiti false o non definiti, non specializzarli. vale a dire

struct B1 { // specialize Resolve for this case 
    static const bool my_value = true; 
}; 
struct B2 { // don't specialize 
    static const bool my_value = false; 
}; 
struct B3 {}; // don't specialize 

Quando si applica il trucco sopra il B1 dà l'errore di compilazione:

Resolve<B1>::value; 

error: template argument ‘T::my_value’ involves template parameter(s)

Mi rendo conto che questo può essere ottenuto con metodi alternativi. Tuttavia, sono interessato a sapere, perché dà l'errore del compilatore qui e può essere risolto in questo stesso codice?

risposta

20

In realtà quello che stai facendo è proibito dalla sezione §14.5.4/9 che dice,

A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.

Il trucco potrebbe essere utilizzando un tipo per il parametro secondo modello così, incapsulando il non -tipo valore, come descritto di seguito:

template<bool b> struct booltype {}; 

template<typename T, typename B = booltype<true> > 
struct Resolve 
{ 
    static const bool value = false; 
}; 

template<typename T> 
struct Resolve<T, booltype<T::my_value> > 
{ 
    static const bool value = true; 
}; 

Ora compile fines.

+0

Soluzione piacevole. Ho modificato alcune parti e l'esempio. Per la mia specifica esigenza volevo esplorare il trucco di bool' piuttosto che il trucco di void_ per SFINAE. Inoltre, se è vietato dagli standard, penso che dovrei accettare questa risposta, perché non vedo altra via d'uscita. – iammilind

+0

Bene, la modifica è ok. Ho pensato che potevi usare il membro in 'bool2type', ecco perché l'ho aggiunto. Ma se non ne hai bisogno, allora va benissimo per me. – Nawaz

+0

Ah, questa è esattamente la soluzione di cui avevo bisogno per il mio problema. [Domanda 15115109] (http://stackoverflow.com/questions/15115109/how-to-convert-templated-function-overloads-to-partial-specialized-templated-cla) Ho fatto un ulteriore passo avanti usando std :: integral_constant e quelli che sono direttamente disponibili tramite type_traits '":: type" member. –

Problemi correlati