11
votes

Spécialisation de la méthode partielle C ++

y a-t-il une spécialisation partielle pour la méthode de la classe de modèle?

template <class A> void C<A, CObject>::foo() {};


1 commentaires

Il y a quelques manières montrées sur d'autres réponses: Stackoverflow.com/Questtions/1501357/...


5 Réponses :


1
votes

Puisque la classe est le modèle, vous devez spécialiser cela:

template <class A>
class C<A, CObject> 
{
   void foo() { ... }
}


1 commentaires

Je suis déjà spécialisé de classe, mais je dois exactement besoin de spécialiser la méthode :)



0
votes

Si je me souviens bien, vous ne pouvez pas faire de spécialisation partielle de modèles pour les fonctions. Je ne sais pas si cela est inclus dans c ++ 0x

MISE À JOUR: (En attente de confirmation) Comme indiqué dans les commentaires, une spécialisation partielle de modèles de fonctions est possible dans C ++ 0x.


3 commentaires

Cette restriction est levée sur C ++ 0x


@ynngvedh, avez-vous une référence pour cette "mise à jour:" Note? Je n'ai pas encore entendu parler de cela. AFAIK, ils viennent de liftir des arguments par défaut - c'est-à-dire que vous pouvez avoir des arguments par défaut dans les modèles de fonctions.


@libt, pas de référence. Je viens de supposer que la norrow savait ce qu'il parlait comme je ne suis pas expert sur C ++ 0x. Quelqu'un peut-il connaître cela? Je vais mettre à jour de manière appropriée.



12
votes

Si vous avez déjà une classe spécialisée, vous pouvez donner une implémentation différente de FOO code> dans la classe spécialisée: xxx pré>


pour spécialiser la fonction membre dans Visual C ++ 2008 Vous pouvez aussi faire un modèle IT aussi: P>

template<typename A, typename B>
class C
{
  template<typename T>
  void foo();

  template<>
  void foo<CObject>();
};


5 commentaires

Alors que la seconde est correcte, le premier est faux - vous ne pouvez pas mettre des spécialisations explicites en classe - et même si vous mettez la spécialisation du modèle dans la portée du vide de noms - si vous spécialisez un modèle, tous ses modèles joints doivent également être spécialisés. :( Donc tu dois rester avec la deuxième façon.


Donc, cela ne fonctionnera pas par exemple: Modèle Modèle <> NOID C :: FOO () {} , car pendant la fonction de membre Le modèle est spécialisé, l'extérieur n'est pas encore. Vous pouvez faire l'inverse de l'inverse bien que Modèle <> Modèle NOID C :: FOO () {} Mais je soupçonne que ce n'est pas ce qu'il veut faire - .-


Il semble d'abord ne pas être une conformité standard NO C ++ 03, mais cela fonctionne dans Visual C ++ 2008. Il ressemble à une extension C ++ 0x (14.6.5.3 Membres de spécialisations de modèle de classe).


Réponse correcte, deuxième option toujours là pour référence.


Eh bien, l'exemple dans 14.6.5.3/2 dans le brouillon C ++ 0X est une spécialisation partielle. Pour des spécialisations partielles, ces restrictions ne sont pas en place. Ceux-ci peuvent être mis en classe - déjà en C ++ 03. Mais dans votre cas, vous spécialisez explicitement le modèle de fonction. S'ils l'avaient fait dans leur exemple, il serait illégal ASWELL: Modèle Struct A {Modèle Structure B {}; modèle <> structure B {}; }; . Il y a un rapport de problème chez Open-Std.org/ JTC1 / SC22 / WG21 / DOCS / CWG_CLOSE.HTML # 727 Demandant de soulever cette restriction (que je souhaiterais aussi, bien sûr)



8
votes

Je pense qu'il y a un malentendu là-bas.

Il existe deux types de modèles: p>

  • les classes de modèle li>
  • les méthodes de modèle li> ul>

    Dans votre exemple, vous avez une classe de modèle, qui contient bien sûr des méthodes. Dans ce cas, vous devrez spécialiser la classe. P>

    // 1- Inheritance
    template <class A, class B>
    class CBase
    {
      // Everything that does not require specialization
    };
    
    template <class A, class B>
    class C: public CBase<A,B>
             // depending on your need, consider using another inheritance
             // or even better, composition
    {
      void foo(); // generic
    };
    
    template <class A>
    class C<A,CObject> : public CBase<A,CObject>
    {
      void foo(); // specialized
    };
    
    // 2- Friend
    // note the change in signature:
    // - now you need to pass the attributes to be changed
    // - the last parameter helps differentiating the overload
    //   as there is no specialization for functions
    template <class A, class B> void foo(Arg1&, Arg2&, const B&);
    template <class A> void foo(Arg1&, Arg2&, const CObject&);
    
    template <class A, class B>
    class C
    {
      friend template <class, class> foo;
    };
    
    // 3- Delegation
    // same signature as foo in (2)
    template <class A, class B> void bar(Arg1&, Arg2&, const B&);
    template <class A> void bar(Arg1&, Arg2&, const CObject&);
    
    template <class A, class B>
    class C
    {
      void foo() { bar(member1, member2, B()); }
    };
    


0 commentaires

2
votes

Non, il n'y a pas de spécialisation de modèle de fonction partielle en C ++ 0x à ajouter.

comme correctement mentionné ci-dessus, en ce qui concerne les modèles de fonctions fondamentalement 2 choses ont été effectuées:

  • Les arguments de modèle par défaut ont été mis à disposition;
  • Les modèles variadiques ont été introduits.

    Donc, comme avant, les solutions de contournement doivent être utilisées pour "émuler" Spécialisation des modèles de fonctions partielles.


0 commentaires