Domanda

In C ++, si suppone una specializzazione di modello di funzione di agire esattamente come una normale funzione. Questo significa che posso fare quello virtuale?

Ad esempio:

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 mi dà il seguente errore:

  

errore irreversibile C1001:. Un errore interno è verificato nel compilatore

È stato utile?

Soluzione

errore del compilatore Nizza. Per questo tipo di controlli che ho sempre fallback al Comeau compilatore prima di tornare allo standard e controllo.

  

Comeau C / C ++ 4.3.10.1 (6 Ott 2008   11:28:09) per ONLINE_EVALUATION_BETA2   Copyright 1988-2008 Comeau Computing.   Tutti i diritti riservati. MODE: rigorosa   errori C ++ C ++ 0x_extensions

     

"ComeauTest.c", linea 3: errore:   "Virtuale" non è consentito in una funzione   modello             dichiarazione         template void f virtuale ();                            ^

     

"ComeauTest.c", linea 10: errore:   "Virtuale" non è consentito in una funzione   modello             dichiarazione         template void f virtuale ();      ^

Ora, come è stato inviato da un altro utente, il fatto è che la norma non consente di definire i metodi su modelli virtuali. La logica è che per tutti i metodi virtuali, una voce deve essere riservato nel vtable. Il problema è che i metodi del modello saranno definiti solo quando sono stati istanziati (usato). Ciò significa che il vtable finirebbe avente un numero diverso di elementi in ciascuna unità di compilazione, a seconda quanti diversi inviti f () con diversi tipi accadere. Poi l'inferno sarebbe stato sollevato ...

Se quello che vuoi è una funzione template su uno dei suoi argomenti e una versione specifica di essere virtuale (notare la parte dell'argomento) si può fare:

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 si desidera che questo generalizzato per qualsiasi tipo, allora siete fuori di fortuna. Prendere in considerazione un altro tipo di delega, invece di polimorfismo (+ aggregazione delegazione potrebbe essere una soluzione). Maggiori informazioni sul problema in questione aiuterebbe a determinare una soluzione.

Altri suggerimenti

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

  

-3- Un modello di funzione membro non deve essere virtuale.

Esempio:

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

Come altri hanno notato, questo non è il codice legale perché un modello di funzione membro non può essere dichiarato virtual.

Eppure, anche Visual Studio 2012 soffoca su questo: errore del compilatore C ++ interna su Visual Studio 2012 Clicca qui per full size

registri eventi indicano che il compilatore si è schiantato su 0xC0000005 o STATUS_ACCESS_VIOLATION. E 'strano come una certa (illegale) costrutto di codice può fare la segfault compilatore ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top