2011-10-15 10 views
9

Traté de poner en práctica un SFINAE utilizando bool (a diferencia populares void_trick):SFINAE trató con bool da error del compilador: "parámetro de plantilla 'T :: valor' implica parámetro de plantilla"

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; 
    }; 

El objetivo es especialice, las clases que tienen static const bool my_value = true; definidas dentro de él. Si están definidos false o no están definidos, no los especialices. es decir,

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 

Al aplicar el truco anterior sobre B1 que da el error de compilación:

Resolve<B1>::value; 

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

Soy consciente de que esto puede lograrse con métodos alternativos. Sin embargo, estoy interesado en saber, ¿por qué da error de compilación aquí y se puede resolver en este código?

Respuesta

20

En realidad lo que está haciendo está prohibido por la sección §14.5.4/9, que 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.

El truco podría ser el uso de un tipo para el segundo parámetro de plantilla, así, que encapsula el no -type valor, como se describe a continuación:

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; 
}; 

Ahora compile fines.

+0

Buena solución. He editado una parte y el ejemplo. Para mi requisito específico, quería explorar el truco 'bool' en lugar del truco' void_' para SFINAE. Además, si está prohibido por estándar entonces, creo que debería aceptar esta respuesta, porque no veo otra salida. – iammilind

+0

Bueno, la edición está bien. Pensé que podrías usar el miembro en 'bool2type', por eso lo agregué. Pero si no lo necesitas, entonces está perfectamente bien conmigo. – Nawaz

+0

Ahh, esta es exactamente la solución que necesitaba para mi problema. [Pregunta 15115109] (http://stackoverflow.com/questions/15115109/how-to-convert-templated-function-overloads-to-partial-specialized-templated-cla) Di un paso más al usar std :: integral_constant , y los que están directamente disponibles a través de type_traits '":: type" miembro. –

Cuestiones relacionadas