2010-10-21 6 views
0

Est-il possible d'avoir une classe modélisée et aussi de modéliser le constructeur avec un autre type?classe modélisée avec un constructeur basé sur un modèle (d'un autre type)

quelque chose comme ceci:

template<typename T1> 
class Foo{ 
    template<typename T2> 
    Foo(T1 aBar, T2 dummyArgument){ 
     bar = aBar; 
     bytesOfT2 = sizeof(T2); 
    }; 

    int bytesOfT2; 
    T1 bar; 
}; 

est-ce possible? et si oui, comment pourrais-je appeler un tel constructeur? Dois-je considérer quelque chose en ce qui concerne les fichiers header et cpp?

merci! // edit: mon exemple particulier est en fait même un peu plus compliqué. j'ai

template <typename U1, U2> 
class Foo{ 
    U1 var1; 
    U2 var2; 
}; 

template <typename T1> 
class Bar{ 
    template<typename T2, typename T3> 
    Bar(Foo<T2,T3> aFoo, T1 aVal){ 
     val=aVal; 
     bytesOfT2=sizeof(T2); 
     bytesOfT3=sizeOf(T3); 
    }; 

int bytesOfT2; 
int bytesOfT3; 
T1 val; 
}; 

ce que cela signifie que je peux ici appeler le constructeur juste avec une variable de type Foo et il devrait sélectionner automatiquement le bon constructeur acording à la version de Foo (par exemple, si la variable i passe est de tapez Foo devrait-il automatiquement mettre T2 à bool et T3 à flotter)?

+0

Que voulez-vous dire par « Ai-je besoin d'envisager quelque chose en ce qui concerne les fichiers de tête et cpp? » –

+0

mmmh - pour certaines raisons (dont je ne me souviens pas) parfois je devais mettre une seule ligne comme "modèle de classe Foo ;" dans le fichier cpp si jamais je voulais pouvoir utiliser la classe Foo avec le type de template bool. (donc j'avais besoin de faire cela pour chaque type que je voulais utiliser avec la classe modélisée) – Mat

+0

Ah. Vous pouvez lire à propos de pourquoi c'est le cas dans [la FAQ C++ Lite] (http://www.parashift.com/c++faq-lite/templates.html#faq-35.12) (cette entrée et les entrées suivantes discutent du "problème" et comment vous le résoudre, il est généralement préférable d'implémenter le modèle entier dans le fichier d'en-tête). –

Répondre

8

Oui, un modèle de classe peut avoir un modèle de constructeur. Vous l'appelez comme vous appelez tout autre constructeur:

Foo<int> my_foo(42, 0.0); 

Cela appelle le modèle de constructeur avec T1 = int (car T1 est un paramètre de modèle de classe et l'argument de modèle de classe est int) et T2 = double (parce que T2 est un modèle de fonction argument et est déduit de l'argument 0.0).

Tous les arguments du modèle doivent pouvoir être déduits des arguments de la fonction, sinon le modèle du constructeur ne peut pas être appelé. Il n'existe aucun moyen de spécifier explicitement les arguments de modèle pour un modèle de constructeur.

+0

ah! donc je peux réellement passer une variable arbitraire en tant que deuxième argument et le compilateur générera automatiquement la bonne version du constructeur pour moi? Je n'ai même pas besoin de mentionner le type dans les <> parenthèses en quelque sorte? – Mat

+0

@Mat: Oui. La déduction des arguments a lieu pour les modèles de constructeur, tout comme pour les autres modèles de fonctions. –

+0

qu'en est-il de mon exemple étendu (voir ci-dessus) va-t-il sélectionner les «sous-types» appropriés si je fournis une variable typée Foo comme argument? – Mat

0

Vous pouvez également utiliser plus d'un template type:

template<typename T1, typename T2> 
class Foo{ 
public: 
    Foo(T1 aBar, T2 dummyArgument){ 
     bar = aBar; 
     bytesOfT2 = sizeof(T2); 
    } 

private: 
    int bytesOfT2; 
    T1 bar; 
}; 
+0

Je ne veux pas cela, je veux seulement que le constructeur soit d'un autre type de variable – Mat

+0

@Mat: je n'ai pas eu cela en répondant. :( – Donotalo

1

Oui, il est possible. Comme pour appeler le constructeur, vous fournissez simplement un argument de type T1 et un deuxième argument de type T2. C'est tout (à moins d'entrer dans une discussion terminologique sur "appeler").

Par ailleurs, au lieu de la première initialisation par défaut bar puis lui assigner, vous devez simplement l'initialiser directement, comme

template< class T2 > 
Foo(T1 const& aBar, T2 const& dummyArgument) 
    : bar(aBar) 
    , bytesOfT2(sizeof(T2)) 
{} 

Consulter les constructeurs et initializers dans votre C++ manuel.

Vive & HTH.,

+0

ah - je ne savais pas que je peux utiliser des expressions dans les listes d'initialisation - merci! – Mat

Questions connexes