Question

En C ++, une spécialisation de modèle de fonction est censé agir exactement comme une fonction normale. Est-ce que cela signifie que je peux faire un? Virtuel

Par exemple:

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 donne l'erreur suivante:

  

erreur fatale C1001:. Une erreur interne est produite dans le compilateur

Était-ce utile?

La solution

Nice erreur du compilateur. Pour ce type de contrôles que je REPLI toujours Comeau compilateur avant de retourner à la norme et la vérification.

  

Comeau C / C ++ 4.3.10.1 (6 octobre 2008   11:28:09) pour ONLINE_EVALUATION_BETA2   Droit d'auteur 1988-2008 Comeau Computing.   Tous les droits sont réservés. MODE: stricte   erreurs C ++ C ++ 0x_extensions

     

"ComeauTest.c", ligne 3: Erreur:   « Virtuelle » n'est pas autorisé dans une fonction   modèle             déclaration         virtual void modèle f ();                            ^

     

"ComeauTest.c", ligne 10: Erreur:   « Virtuelle » n'est pas autorisé dans une fonction   modèle             déclaration         virtual void modèle f ();      ^

Maintenant, comme il a été posté par un autre utilisateur, le fait est que la norme ne vous permet pas de définir des méthodes virtuelles templated. La raison est que pour toutes les méthodes virtuelles, une entrée doit être réservé à la vtable. Le problème est que les méthodes de modèle ne seront définis quand ils ont été instancié (utilisé). Cela signifie que le vtable finirait par avoir un nombre différent d'éléments dans chaque unité de compilation, selon le nombre de différents appels à f () avec différents types se produisent. Puis l'enfer serait soulevée ...

Si ce que vous voulez est une fonction sur l'un basé sur un modèle ses arguments et une version spécifique étant virtuelle (note de la part de l'argument), vous pouvez le faire:

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 vous voulez que cette généralisée pour tout type, alors vous êtes hors de la chance. Prenons un autre type de délégation au lieu de polymorphisme (agrégation + délégation pourrait être une solution). Plus d'informations sur le problème à portée de main contribuerait à déterminer une solution.

Autres conseils

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

  

-3- Un modèle de fonction membre ne doit pas être virtuel.

Exemple:

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

Comme d'autres l'ont noté, ce n'est pas un code juridique, car un modèle de fonction de membre ne peut être déclarée virtual.

Pourtant, même Studio 2012 de Visual selfs à ce sujet: C ++ erreur du compilateur interne sur Visual Studio 2012 Cliquez ici pour la taille complète

Les journaux d'événements indiquent que le compilateur est écrasé sur 0xC0000005 ou STATUS_ACCESS_VIOLATION. Il est drôle comment une certaine construction de code (illégal) peut rendre le compilateur segfault ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top