Constructeur de template C ++

Je souhaite avoir une classe non-template avec un constructeur de template sans arguments.

Autant que je sache, il est impossible de l’avoir (car il serait en conflit avec le constructeur par défaut – ai-je raison? ), Et la solution est la suivante:

class A{ template  A(U* dummy) { // Do something } }; 

Peut-être y a-t-il une meilleure alternative pour cela (ou une meilleure solution de contournement)?

Il n’y a aucun moyen de spécifier explicitement les arguments de modèle lors de l’appel d’un modèle de constructeur, ils doivent donc être déduits par déduction d’argument. C’est parce que si vous dites:

 Foo f = Foo(); 

Le est la liste des arguments du modèle Foo , pas pour son constructeur. Il n’y a nulle part où aller la liste des arguments du constructeur.

Même avec votre solution de contournement, vous devez toujours passer un argument pour appeler ce modèle de constructeur. Ce que vous essayez d’atteindre n’est pas du tout clair.

Vous pouvez créer une fonction d’usine basée sur un modèle:

 class Foo { public: template  static Foo* create() // could also return by value, or a smart pointer { return new Foo(...); } ... }; 

Pour autant que je sache, il est impossible de l’avoir (car il serait en conflit avec le constructeur par défaut – ai-je raison?)

Vous avez tort. Cela ne contredit en aucune façon. Vous ne pouvez pas appeler ça jamais.

Des points:

  • Si vous déclarez un constructeur (y compris un constructeur), le compilateur s’abstiendra de déclarer un constructeur par défaut.
  • À moins que vous ne déclariez un constructeur de copie (pour une classe X qui prend X ou X& ou X const & ), le compilateur générera le constructeur de copie par défaut.
  • Si vous fournissez un constructeur de modèle pour la classe X qui prend T const & ou T ou T& le compilateur générera néanmoins un constructeur de copie non basé sur un modèle, même si vous pensez peut-être que lorsque T = X la déclaration correspond à la déclaration copy-constructor.
  • Dans ce dernier cas, vous voudrez peut-être fournir un constructeur de copie non basé sur un modèle avec celui basé sur un modèle. Ils ne seront pas en conflit. Lorsque X est passé, le non-décrit sera appelé. Sinon le modèle

HTH

 templatestruct types{using type=types;}; templatestruct tag{using type=T;}; templateusing type_t=typename Tag::type; 

Les aides ci-dessus vous permettent de travailler avec des types en tant que valeurs.

 class A { template A( tag ); }; 

le tag est une variable sans état autre que le type carie. Vous pouvez l’utiliser pour transmettre une valeur de type pur à une fonction de modèle et en déduire le type par la fonction de modèle:

 auto a = A(tag{}); 

Vous pouvez passer dans plus d’un type:

 class A { template A( types ); }; auto a = A(types{}); 

Vous pourriez faire ceci:

 class C { public: template  C(T*); }; template  T* UseType() { static_cast(nullptr); } 

Ensuite, pour créer un object de type C utilisant int comme paramètre de modèle pour le constructeur:

 C obj(UseType()); 

Comme vous ne pouvez pas transmettre de parameters de modèle à un constructeur, cette solution convertit essentiellement le paramètre template en un paramètre normal. L’utilisation de la fonction UseType() lors de l’appel du constructeur indique clairement à quelqu’un qui regarde le code que le but de ce paramètre est d’indiquer au constructeur quel type utiliser.

Un cas d’utilisation serait que le constructeur crée un object de classe dérivé et l’affecte à une variable membre qui est un pointeur de classe de base. (Le constructeur doit savoir quelle classe dérivée utiliser, mais la classe elle-même n’a pas besoin d’être basée sur un modèle puisque le même type de pointeur de classe de base est toujours utilisé.)

essayez de faire quelque chose comme

 template class A{ A(){ A(this) } A( A* a){ //do something } A( A* a){ //do something } . . . }; 

Voici une solution de contournement.

Créez une sous-classe de gabarit B de A. Faites la partie indépendante de la structure de l’argument template dans le constructeur de A. Effectuez la partie dépendant de l’argument template dans le constructeur de B.