2010-08-18 5 views
0

Je suis actuellement en train de lutter pour obtenir le code suivant à compiler. Tout d'abord le fichier d'en-tête contenant une classe avec un modèle de méthode:Comment utiliser les arguments passer-par-référence du type de modèle dans les modèles de méthode?

// ConfigurationContext.h 

class ConfigurationContext 
{ 
    public: 
    template<typename T> T getValue(const std::string& name, T& default) const 
     { 
      ... 
     } 
} 

Ailleurs Je veux appeler cette méthode comme ceci:

int value = context.getValue<int>("foo", 5); 

Là, je l'erreur suivante:

error: no matching function for call to 'ConfigurationContext::getValue(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int)' 

J'ai vérifié les erreurs évidentes comme des inclusions manquantes et des trucs comme ça. Mais tout semble être bon. J'ai essayé de retirer le passage par référence de l'argument de type de modèle comme celui-ci:

template<typename T> T getValue(const std::string& name, T default) const ... 

Ensuite, il compile sans erreur et fonctionne aussi bien, mais je voudrais encore passer une référence ici ...

Est-ce que quelqu'un sait ce qui se passe ici et comment faire ce travail?

Répondre

5

5 est un littéral, et vous ne pouvez pas lier des littéraux à des références non const. Soit prendre T par copie ou par const Référence:

template<typename T> T getValue(const std::string& name, const T& def) const 

(BTW, je doute que votre compilateur accepte T default, car default est un mot-clé et ne doit pas être utilisé comme identifiant.)

La raison pour laquelle vous ne peut pas faire cela parce que prendre des arguments par référence non-const implique généralement que l'appelé pourrait changer la valeur et de tels changements devraient refléter chez l'appelant. (Voir How to pass objects to functions in C++?) Cependant, vous ne pouvez pas modifier les littéraux ou les temporaires. Vous n'êtes donc pas autorisé à les transmettre à des références non-const.

+0

Bien sûr, cela a du sens maintenant ... Je ne devrais probablement plus coder en ce moment (2:46 CEST). Merci pour cette aide rapide! (Oh et je n'utilise pas réellement T par défaut dans mon code, juste raccourci tout pour le rendre plus clair ...) –

+0

Je me demande pourquoi le compilateur ne peut pas donner un message significatif dans ce cas. – Chubsdad

+0

@chubsdad: C++ est un tel langage malicieux à analyser, les implémenteurs sont plutôt occupés à essayer de faire accepter le code _valid_ par leurs compilateurs et faire les bonnes suppositions sur ce qui s'est passé en cas de code invalide prend du temps. (Comeau, probablement le compilateur le plus conforme aux normes, est également livré avec de très bons messages d'erreur.) Et, pour les normes C++, ce message d'erreur n'est pas si grave. Au moins, ce n'est pas vraiment trompeur. (Supprimez le point-virgule à la fin de la déclaration d'une classe qui est la dernière chose dans un en-tête si vous voulez voir un message d'erreur qui est trompeur pour les débutants.) – sbi

Questions connexes