C ++: instancier une classe basée sur un argument

Je trouve souvent le besoin d’utiliser le modèle suivant:

template class SomeClass : public Base { SomeClass(const T& t) {...} ... }; template SomeClass* makeSomeClass(const T& t) { return new SomeClass(t); } 

Et pour l’utiliser:

 Base* = makeSomeClass(123); 

Ceci est utile lorsque je ne souhaite pas spécifier explicitement T car il s’agit d’un processus très complexe (types de fonction, etc.) et l’argument de la fonction peut en déduire le type implicitement.
Y a-t-il un moyen de faire cela sans la fonction “make” supplémentaire? Pourquoi la déduction de modèle fonctionne-t-elle uniquement dans les arguments de fonction et non dans les arguments de constructeur?

Non, il n’y a aucun moyen de faire cela sans une fonction make supplémentaire.

La raison pour laquelle cela ne fonctionne pas avec les constructeurs est parce que ce serait ridiculement compliqué. Considère ceci:

 template  struct Foo { Foo(const T& val) { ... } Foo(const Foo& other) { ... } // Copy constructor }; Foo x; 

Et si j’appelle alors:

 Foo(x); 

Est-ce que cela me donne un Foo< Foo > ou est-ce que j’appelle le constructeur de copie pour un Foo ?

Ce serait ambigu dans trop d’endroits, la fonction supplémentaire est donc nécessaire.

Notez que vous pouvez automatiser un peu la création de fonctions en utilisant des modèles de templates:

 template  

Ensuite, vous pouvez utiliser:

 make(123); // returns a SomeClass 

Cela fonctionne dans les arguments du constructeur, si le constructeur est lui-même un template. La différence est que lorsque vous utilisez votre aide, vous utilisez un modèle de fonction , dans lequel le compilateur peut déduire le type. Sans l’aide, vous utilisez un modèle de classe , dans lequel le compilateur devrait en déduire le type avant d’appeler le constructeur (non modèle).

Y at-il un moyen sans la fonction supplémentaire? Non il n’y en a pas. Pourquoi la déduction ne fonctionne que pour les fonctions? Parce qu’avec les fonctions, vous fournissez des arguments. Si cela était autorisé pour les classes, le seul moyen de déduire les parameters du modèle serait dans le cas où un constructeur était appelé pour l’initialisation, ce qui crée de nombreuses règles et exceptions supplémentaires et complique les choses