Está haciendo una plantilla de especialización función jurídica virtual?
-
09-09-2019 - |
Pregunta
En C ++ una especialización de plantilla de función para actuar exactamente como una función normal. ¿Eso significa que puedo hacer uno virtual?
Por ejemplo:
struct A
{
template <class T> void f();
template <> virtual void f<int>() {}
};
struct B : A
{
template <class T> void f();
template <> virtual void f<int>() {}
};
int main(int argc, char* argv[])
{
B b;
A& a = b;
a.f<int>();
}
Visual Studio 2005 me da el siguiente error:
error fatal C1001:. Un error interno se ha producido en el compilador
Solución
Niza error del compilador. Para este tipo de comprobaciones siempre repliegue a la Comeau compilador antes de volver a la norma y la comprobación.
Comeau C / C ++ 4.3.10.1 (06 de octubre 2008 11:28:09) para ONLINE_EVALUATION_BETA2 Derechos de Autor 1988-2008 Comeau Computing. Todos los derechos reservados. MODO: estricta errores C ++ C ++ 0x_extensions
"ComeauTest.c", línea 3: error: "Virtual" no está permitido en una función modelo declaración plantilla virtual void f (); ^
"ComeauTest.c", línea 10: error: "Virtual" no está permitido en una función modelo declaración plantilla virtual void f (); ^
Ahora, ya que ha sido enviado por otro usuario, el hecho es que la norma no permite definir con plantilla métodos virtuales. La razón es que para todos los métodos virtuales, una entrada debe reservarse en la viable. El problema es que sólo se definirán métodos plantilla cuando se han instanciado (utilizado). Esto significa que la viable sería llegar a tener un número diferente de elementos en cada unidad de compilación, dependiendo del número de llamadas a diferentes f () con diferentes tipos ocurren. Entonces se armó ...
Si lo que desea es una función de plantilla en uno de sus argumentos y una versión específica de ser virtual (tenga en cuenta la parte del argumento) puede hacerlo:
class Base
{
public:
template <typename T> void f( T a ) {}
virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}
Si desea que esta generalizada para cualquier tipo, entonces estás de suerte. Considere otro tipo de delegación en lugar de polimorfismo (agregación + delegación podría ser una solución). Más información sobre el problema en cuestión ayudaría a determinar una solución.
Otros consejos
De acuerdo con http://www.kuzbass.ru:8086/docs /isocpp/template.html ISO / IEC 14882: 1998:
-3- Una plantilla de función miembro no será virtual.
Ejemplo:
template <class T> struct AA {
template <class C> virtual void g(C); // Error
virtual void f(); // OK
};
Como otros han señalado, esto no es el código legal porque una plantilla de función miembro no puede ser declarada virtual
.
Sin embargo, incluso Visual Studio 2012 se ahoga con esto: Haga clic para ampliar
Los registros de sucesos indican que el compilador se estrelló en 0xC0000005
o STATUS_ACCESS_VIOLATION
. Es curioso cómo una cierta (ilegal) construcción de código puede hacer que la violación de segmento compilador ...