2012-03-27 7 views
6

Duplicar posibles:
How to use enable_if to enable member functions based on template parameter of classimpulso :: enable_if_c trabajar

que tienen una plantilla de clase:

template<typename T, size_t N> class Vector 

Quiero habilitar específica para constructores N, entonces lo hago:

Vector(typename boost::enable_if_c<N==2, T>::type const &e0, T const &e1) { 
    data[0] = e0; 
    data[1] = e1; 
} 

Pero el compilador (MSVC 2010 SP1) me da un error en lugar de aplicar SFINAE. El error es:

error C2039: 'type' : is not a member of 'boost::enable_if_c<B,T>' 
     with 
     [ 
      B=false, 
      T=float 
     ] 

¿Cuál es el problema? ¿Es un problema conocido? ¿Cómo puedo arreglarlo? ¿Es la única solución para usar static_assert?

Editar: GCC no tiene éxito, ya sea: http://ideone.com/7Ejo8

+0

¿Se puede publicar un SSCE en ideone (y mostrarlo compilando correctamente en gcc)? –

+0

@Ben Voigt: GCC tampoco compila. –

+0

@Vlad Lazarenko: Pero allí no se describe muy bien cómo solucionarlo. –

Respuesta

5

No puede utilizar enable_if para permitir/denegar funciones miembro en base a los parámetros de plantilla de la clase: enable_if sólo se puede aplicar en las plantillas de función o de clase.

En su caso, la única solución que se me ocurre es especializar toda la clase, ya sea usando enable_if o más simplemente con especialización parcial. Puede poner los miembros comunes en una clase base común, para evitar repetirlos:

#include <cstdio> 

template<typename T, std::size_t N> 
struct VectorCommon 
{ 
    std::size_t size() { return N; } 
    void add(T const & element) { } 
}; 

template <typename T, std::size_t N> 
struct Vector : VectorCommon<T, N> 
{ 
}; 

template <typename T> 
struct Vector<T, 2> : VectorCommon<T, 2> 
{ 
    Vector(T const & e0, T const & e1) {} 
}; 

int main() 
{ 
    //Vector<int, 100> v100(12, 42); // compile error 

    Vector<char, 2> v2('a', 'b'); // ok 
}