Dado:especialización parcial de un método en una clase de plantilla
struct A
{
virtual bool what() = 0;
};
template<typename T, typename Q>
struct B : public A
{
virtual bool what();
};
quiero especializar parcialmente what
como:
template<typename T, typename Q>
bool B<T, Q>::what()
{
return true;
}
template<typename Q>
bool B<float, Q>::what()
{
return false;
}
pero parece que esto no es posible (es en C++ 11) así que traté SFINAE:?
template<typename T>
typename std::enable_if<std::is_same<T, float>::value, bool>::type B<T>::what()
{
return true;
}
template<typename T>
typename std::enable_if<!std::is_same<T, float>::value, bool>::type B<T>::what()
{
return false;
}
Esto también no funciona, no tengo ni idea de por qué, sin embargo, ¿alguien? Así que encontré this thread y terminó con:
template<typename T, typename Q>
struct B : public A
{
virtual bool what()
{
return whatimpl(std::is_same<T, float>());
}
bool whatimpl(std::false_type)
{
return false;
}
bool whatimpl(std::true_type)
{
return true;
}
};
Esta solución final funciona, pero por qué no funciona el enable_if
técnica? También estoy muy abierto a las sugerencias de una respuesta más clara que todavía no he encontrado.
Simplifiqué mis ejemplos tanto como sea posible - en mi caso de uso real, no se llama what()
lo y de hecho lo hace un poco de trabajo, y querré 'especializarse' en un tipo definido por el usuario, no float
.
@Nawaz Me di cuenta de eso, pero esto es solo un caso simplificado para mostrar lo que estoy tratando de hacer :) Lea la última línea de la publicación. – David
_what_ no es un método de plantilla, para anular A :: what() debe ser un único método no plantilla de la plantilla de clase B. No puede especializar el método sin plantilla, ni con enable_if ni con ningún otro techique. Sin embargo, usted puede especializar toda la clase B – user396672
@ user396672 Entonces, ¿por qué funciona esto (especialización completa en lugar de parcial): 'plantilla <> bool B :: what() { return false; } ' –
David