2010-08-10 5 views
2

J'ai ClassA<ARG_TYPE> et ClassB<ARG_TYPE>. Maintenant, je veux utiliser ClassC, qui a commun ARG_TYPE et a mentionné les classes comme arguments de modèle.Arguments de modèle

ClassC<ARG_TYPE, ClassA<ARG_TYPE>, ClassB<ARG_TYPE>> est facile.

Mais est-il possible de déclarer ClassC<ARG_TYPE, ClassA, ClassB> pour que les classes A et B sachent utiliser ARG_TYPE comme argument de modèle?

Répondre

5

Oui, cela peut être fait, grâce à l'utilisation de "template template arguments".

Declare ClassC comme suit:

template<typename Arg, 
    template<typename T_Arg> class T_ClassA, 
    template<typename T_Arg> class T_ClassB> 
class ClassC 
{ 
    typedef T_ClassA<Arg> MyClassA; 
    typedef T_ClassB<Arg> MyClassB; 

    // Use MyClassA and MyClassB 
}; 

Utilisez

ClassC<Arg, ClassA, ClassB> 

et il devrait fonctionner correctement.

0

Cela peut être fait, mais je n'aime pas beaucoup cette solution.

Le problème est que suppose que je définir:

template <class Arg, class Policy> class Polymorph; 

qui est une généralisation de votre type MyClassA mais dont le comportement peut être modifié (à la compilation) grâce à l'utilisation des politiques (pensez Allocator pour conteneur standard par exemple).

Je ne peux pas utiliser l'interface, car ma classe prend 2 paramètres alors que votre spécification ne fonctionne qu'avec un ...

Par conséquent, je préfère de loin la première approche, même si un peu plus bavard. Afin de bénéficier à la fois que vous avez 2 solutions (les deux impliquant canard typage):

  • vous suffit de définir une première classe en utilisant la première approche, puis une deuxième classe en utilisant la seconde approche qui transmet la (maintenant terminée) arguments à la première. De cette façon, les personnes dont les classes de modèles ne correspondent pas à vos exigences pourront toujours bénéficier de votre travail.
  • il appartient à l'utilisateur de fournir le canard-typage pour sa classe afin qu'il crée une classe d'un argument d'une classe de plusieurs arguments. L'héritage et le modèle ne se mélangent pas bien, donc cela peut causer des problèmes et je serais en faveur de l'idée précédente (mettre le fardeau sur l'auteur de la bibliothèque).

Cela change avec l'arrivée de C++ 0x: la solution devient plus tard un template'd typedef qui fonctionne beaucoup mieux :)

Voici un exemple en C++ 0x:

template <class Arg, template <class> class ClassA> 
struct MyTemplate 
{ 
    typedef ClassA<Arg> classA_type; 
}; 

template <class Arg, class Policy> class Polymorph; 

// C++0x required for following declaration 
template <class Arg> 
typedef Polymorph<Arg, ConservativePolicy> ConservativePolymorph; 

typedef MyTemplate<int, ConservativePolymorph> MyTemplateC; 

Si vous n'avez pas de C++ 0x disponible, évitez ceci et réutilisez la manière STL, même si c'est plus bavard.

Questions connexes