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 cela entrerait en conflit avec le constructeur par défaut - c'est vrai?), et la solution de contournement est la suivante:
class A{
template <typename U> A(U* dummy) {
// Do something
}
};
Peut-être qu'il y a une meilleure alternative pour ceci (ou une meilleure solution de contournement)?
Il n’existe aucun moyen de spécifier explicitement les arguments du 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<int> f = Foo<int>();
Le <int>
est la liste des arguments de modèle pour le type Foo
, pas pour son constructeur. Il n'y a nulle part où aller pour la liste d'arguments du modèle de 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'accomplir n'est pas du tout clair.
Vous pouvez créer une fonction d'usine basée sur un modèle:
class Foo
{
public:
template <class T> static Foo* create() // could also return by value, or a smart pointer
{
return new Foo(...);
}
...
};
Autant que je sache, il est impossible de l'avoir (car cela entrerait en conflit avec le constructeur par défaut - ai-je raison?)
Vous avez tort. Cela ne crée aucun conflit. Vous ne pouvez pas l'appeler jamais.
template<class...>struct types{using type=types;};
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
les aides ci-dessus vous permettent de travailler avec des types en tant que valeurs.
class A {
template<class T>
A( tag<T> );
};
le tag<T>
type est une variable sans état autre que le type carie. Vous pouvez l'utiliser pour passer une valeur de type pur à une fonction de modèle et en déduire le type à l'aide de la fonction de modèle:
auto a = A(tag<int>{});
Vous pouvez passer dans plus d'un type:
class A {
template<class T, class U, class V>
A( types<T,U,V> );
};
auto a = A(types<int,double,std::string>{});
Des points:
X
ou X&
ou X const &
) le compilateur générera le constructeur de copie par défaut.T const &
ou T
ou T&
_ alors le compilateur générera néanmoins un constructeur de copie par défaut sans modèle, même si vous pensez peut-être que cela ne devrait pas car, lorsque T = X, la déclaration correspond à la déclaration du constructeur de copie.HTH
Vous pourriez faire ceci:
class C
{
public:
template <typename T> C(T*);
};
template <typename T> T* UseType()
{
static_cast<T*>(nullptr);
}
Ensuite, pour créer un objet de type C
, utilisez int
comme paramètre de modèle du constructeur:
C obj(UseType<int>());
Comme vous ne pouvez pas transmettre de paramètres de modèle à un constructeur, cette solution convertit essentiellement le paramètre de modèle en paramètre standard. L'utilisation de la fonction UseType<T>()
lors de l'appel du constructeur indique clairement à ceux qui consultent le code que l'objectif de ce paramètre est d'indiquer au constructeur le type à utiliser.
Un cas d'utilisation pour cela serait si le constructeur crée un objet de classe dérivée et l'assigne à 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, car le même type de pointeur de classe est toujours utilisé.)
essayez de faire quelque chose comme
template<class T, int i> class A{
A(){
A(this)
}
A( A<int, 1>* a){
//do something
}
A( A<float, 1>* a){
//do something
}
.
.
.
};
Voici une solution de contournement.
Créez un sous-type de modèle B sur A. Créez la partie indépendante de la construction du modèle dans le constructeur de A. Effectuer la partie dépendante du modèle-argument dans le constructeur de B.