118 votes

Pourquoi ne pas en déduire paramètre de modèle de constructeur?

ma question aujourd'hui est assez simple: pourquoi ne peut pas le compilateur de déduire les paramètres de modèle de constructeurs de classe, autant qu'il peut le faire à partir des paramètres de fonction? Par exemple, pourquoi ne pas le code suivant:

template<typename obj>
class Variable {
      obj data;
      public: Variable(obj d)
              {
                   data = d;
              }
};

int main()
{
    int num = 2;
    Variable var(num); //would be equivalent to Variable<int> var(num),
    return 0;          //but actually a compile error
}

Comme je l'ai dit, je comprends que ce n'est pas valide, donc ma question est pourquoi n'est-il pas? Permettant à créer des majeurs syntaxique des trous? Est-il une instance où l'on ne voudrait pas cette fonctionnalité (où déduire un type causerait des problèmes)? J'essaie juste de comprendre la logique derrière l'autorisation de modèle d'inférence pour les fonctions, mais pas pour l'convenablement construit des classes.

Merci

50voto

Drahakar Points 2840

Je pense qu'il n'est pas valide parce que le constructeur n'est pas toujours le seul point d'entrée de la classe (je suis en train de parler constructeur de copie et l'opérateur=). Supposons donc que vous êtes à l'aide de votre classe comme ceci :

MyClass m(string s);
MyClass *pm;
*pm = m;

Je ne sais pas si il serait évident pour l'analyseur de savoir quel type de modèle est le MyClass pm;

Vous ne savez pas si ce que j'ai dit de faire sens, mais n'hésitez pas à ajouter quelques commentaires, c'est une question intéressante.

27voto

Lionel Points 51

Vous ne pouvez pas faire ce que vous demandez, pour des raisons autres personnes ont abordé, mais vous pouvez le faire:

template<typename T>
class Variable {
    public: Variable(T d) {}
};
template<typename T>
Variable<T> make_variable(T instance) {
  return Variable<T>(instance);
}

qui, à toutes fins utiles est la même chose que vous demandez. Si vous aimez l'encapsulation vous pouvez faire make_variable une fonction membre statique. C'est ce que les gens appellent nommé constructeur. Ainsi, non seulement faut-il faire ce que vous voulez, mais c'est presque appelé ce que vous voulez: le compilateur est inférer le paramètre de modèle de l' (nommé) du constructeur.

NB: toute raisonnable compilateur d'optimiser loin l'objet temporaire lorsque vous écrivez quelque chose comme

Variable<T> v = make_variable(instance);

12voto

MSalters Points 74024

Manque encore: Il fait le code suivant assez ambigüe:

int main()
{
    int num = 2;
    Variable var(num);  // If equivalent to Variable<int> var(num),
    Variable var2(var); //Variable<int> or Variable<Variable<int>> ?
}

9voto

Cătălin Pitiș Points 10520

En supposant que le compilateur prend en charge ce que vous avez demandé. Ce code est valide:

Variable v1( 10); // Variable<int>

// Some code here

Variable v2( 20.4); // Variable<double>

Maintenant, j'ai le même type de nom (Variable) dans le code de deux types différents (Variable et Variable). De mon point de vue subjectif, il affecte la lisibilité du code, ou presque. Ayant le même type de nom pour deux types différents dans le même espace de noms semble trompeuse pour moi.

Mise à jour ultérieure: Une autre chose à considérer: partielle (ou complète) de spécialisation de modèle.

Que faire si je me spécialise Variable et n'offrent pas de constructeur comme vous vous attendez?

Je voudrais donc avoir:

template<>
class Variable<int>
{
// Provide default constructor only.
};

Puis-je avoir le code:

Variable v( 10);

Quel doit être le compilateur? Utilisation générique de la Variable de définition de classe pour en déduire qu'elle est Variable, puis découvrir que la Variable n'est pas de fournir un paramètre de constructeur?

6voto

ChetS Points 328

Le C++03 et le C++11 standard ne permet pas de l'argument de modèle de déduction à partir des paramètres passés à la constuructor.

Mais il y a une proposition pour "paramètre du Modèle de la déduction pour les constructeurs" de sorte que vous pouvez obtenir ce que vous demandez pour bientôt.

Voir: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3602.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X