2011-10-15 14 views
9

starałem się wdrożyć SFINAE użyciu bool (w przeciwieństwie do popularnych void_trick):SFINAE próbował z bool daje błąd kompilatora: „szablon argumentem«T :: wartość»obejmuje parametr szablonu”

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

Celem jest Specjalizujemy się w klasach, które mają zdefiniowane w nim static const bool my_value = true;. Jeśli są zdefiniowane jako false lub nie są zdefiniowane, nie specjalizuj się. tj

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 

Stosując powyższą sprawę na B1 daje błąd kompilacji:

Resolve<B1>::value; 

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

Jestem świadomy, że można to osiągnąć z alternatywnych sposobów. Jednak jestem zainteresowany wiedząc, dlaczego tutaj podaje błąd kompilatora i czy można go rozwiązać w tym kodzie?

Odpowiedz

20

Właściwie to, co robisz jest zabronione przez cesarskie §14.5.4/9, który mówi,

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.

Sztuką może być za pomocą typ dla drugiego parametru szablonu, jak również, enkapsulacji non dyspozycji następujące typy wartości, jak opisano poniżej:

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

teraz compile fines.

+0

Przyjemne rozwiązanie. Edytowałem część i przykład. Dla mojego konkretnego wymagania chciałem zbadać sztuczkę 'bool' zamiast sztuczki 'void_' dla SFINAE. Ponadto, jeśli jest to zabronione przez standard, myślę, że powinienem przyjąć tę odpowiedź, ponieważ nie widzę innego wyjścia. – iammilind

+0

Cóż, edycja jest w porządku. Myślałem, że możesz użyć tego elementu w 'bool2type', dlatego dodałem go. Ale jeśli go nie potrzebujesz, to jest dla mnie całkowicie w porządku. – Nawaz

+0

Ahh, to jest dokładnie rozwiązanie, którego potrzebowałem do mojego problemu. [Pytanie 15115109] (http://stackoverflow.com/questions/15115109/how-to-convert-templated-function-overload-to-partial-specialized-templated-cla) Zrobiłem to o krok dalej, używając std :: integral_constant i te, które są bezpośrednio dostępne poprzez człon "type" type_traits. –