Pergunta

Em C ++, uma especialização de modelo função deve agir exatamente como uma função normal. Isso significa que eu posso fazer um virtual?

Por exemplo:

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 dá o seguinte erro:

erro fatal C1001:. Um erro interno ocorreu no compilador

Foi útil?

Solução

erro agradável compilador. Para este tipo de verificações Eu sempre fallback para o Comeau compilador antes de voltar para o padrão e verificação.

Comeau C / C ++ 4.3.10.1 (06 de outubro de 2008 11:28:09) para ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. Todos os direitos reservados. MODO: estrita erros C ++ C ++ 0x_extensions

"ComeauTest.c", linha 3: error: "Virtual" não é permitido em uma função modelo declaração template virtual void f (); ^

"ComeauTest.c", linha 10: erro: "Virtual" não é permitido em uma função modelo declaração template virtual void f (); ^

Agora, como tem sido postado por outro usuário, o fato é que a norma não permitem definir métodos templated virtuais. A lógica é que para todos os métodos virtuais, uma entrada deve ser reservado com o vtable. O problema é que os métodos do molde só irá ser definido quando eles foram instanciado (usada). Isto significa que o vtable que acabam por ter um número diferente de elementos em cada unidade de compilação, dependendo de quantos diferentes chamadas para f () com diferentes tipos acontecer. Em seguida, o inferno seria levantado ...

Se o que você quer é uma função templated em um dos seus argumentos e uma versão específica sendo virtual (observe a parte do argumento), você pode fazê-lo:

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

Se você quer esta generalizada para qualquer tipo, então você está fora de sorte. Considere um outro tipo de delegação em vez de polimorfismo (agregação + delegação pode ser uma solução). Mais informações sobre o problema na mão iria ajudar a determinar uma solução.

Outras dicas

De acordo com a http://www.kuzbass.ru:8086/docs /isocpp/template.html ISO / IEC 14882: 1998:

-3 Um modelo de função de membro não será virtual.

Exemplo:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};

Como outros já mencionado, este não é o código legal porque um modelo de função de membro não pode ser declarada virtual.

No entanto, mesmo Visual Studio 2012 engasga com isto: C ++ erro interno do compilador no Visual Studio 2012 Clique aqui para ampliar

Os logs de eventos indicam que o compilador caiu na 0xC0000005, ou STATUS_ACCESS_VIOLATION. É engraçado como uma certa construção de código (ilegal) pode fazer o compilador segfault ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top