Appel f(const Value<std::string>&)
avec une chaîne littérale nécessiterait deux conversions définies par l'utilisateur (const char[]
==>std::string
==>Value<std::string>
) afin de faire correspondre les paramètres de la fonction, alors que la norme ne permet un.
Je vois deux possibilités pour résoudre cela: soit surcharger le constructeur, soit surcharger f()
.
En supposant que vous posez des questions sur le premier parce que ce dernier n'est pas possible, il existe plusieurs façons de surcharger le constructeur.
Vous pouvez exploiter le fait que les fonctions membres d'un modèle de classe ne sont compilées que si elles sont appelées, et ajoutez un constructeur qui ne compile que lorsque T
est d'un certain type. Bien sûr, si les utilisateurs de votre modèle l'invoquent pour d'autres types, cela entraînera une erreur. Cependant, au lieu de voir un problème dans ce que vous pouvez embrasser en faisant le constructeur d'un modèle de membre:
template<typename U>
Value(const U& value) : m_value(value) { };
De cette façon, tout ce qui peut être converti en T
(ainsi que T
lui-même, bien sûr) est autorisé pour U
.
Ou vous pourriez spécialiser la classe pour std::string
. Malheureusement, vous devrez alors spécialiser toute la classe car il n'y a pas de spécialisation sélective des membres individuels. Dans ce cas, vous pouvez déplacer tout le code dans une classe de base private
(Value
), avec le modèle de base Value
définissant simplement les constructeurs qui redirigent vers les constructeurs de la classe de base, et une spécialisation Value<std::string>
qui ajoute un autre constructeur prenant const char*
.
Je pensais aussi qu'il était implicitement convertible mais le compilateur (g ++) s'en plaint (initialisation invalide de référence). – rve
et non, la chaîne n'est pas un espace réservé – rve
@rve: Je suis désolé, c'était un brainfart à moi. J'ai échoué à voir que vous vouliez appeler 'f()' avec une chaîne C. Je vais réparer ma réponse. – sbi