2010-09-26 13 views
0

Je reçois l'erreur suivante lorsque je compile le code suivant sur Visual Studio 2008/Windows SDK 7erreur de modèle Ambigu ajoutant std :: string à uint dans Visual C++

const UINT a_uint; 
UINT result; 

throw std::runtime_error(std::string("we did ") + a_uint + 
          " and got " + result); 

Ironie du sort, j'ai fini avec ce résultat:

error C2782: 'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(
       const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem 
      )' : template parameter '_Elem' is ambiguous 

quelqu'un peut-il expliquer pourquoi le message d'erreur n'explique pas le vrai problème (qu'il n'y a pas d'opérateur pour + ing ints à cordes)?

+0

J'ai posté ceci parce qu'un ami m'a posé cette question. Je connaissais le correctif, mais pas la raison du message d'erreur. –

Répondre

6

Vous pouvez réduire à ce que

template<typename T> 
void f(T, T); 

int main() { 
f('0', 0); // is T int or char? 
} 

Vous essayez d'ajouter un unsigned int à une chaîne. Cela n'a pas de sens, et la classe std::string n'a pas besoin de prendre de précautions pour ajouter des conversions implicites à char ici car cela cacherait de tels bugs de programmation potentiels.

Essayez de convertir le unsigned int à std::string en nombre décimal/hexadécimal/octal/etc formulaire, puis concaténer (vous pouvez le faire en utilisant std::ostringstream ou boost::lexical_cast) ou corriger le bogue dans d'autres façons vous semble.

0

La prochaine fois s'il vous plaît poster l'erreur complète (il devrait continuer "avec [_Elem =], pourrait être l'un de [liste des surcharges ambiguës]").

Le problème est que vous concaténez UINT avec une chaîne std :: string. Ce n'est pas une opération valide, vous devez d'abord convertir l'UINT en une chaîne std :: string (recherchez Google pour les fonctions pratiques). Le compilateur essaie de faire de son mieux et essaie de faire correspondre certains des opérateurs std :: string à l'UINT. Apparemment, il trouve des allumettes mais celles-ci ne sont certainement pas ce que vous cherchez.

+0

Il n'a rien dit d'autre. –

+0

Hmm, ça aurait dû. Quelle version de Visual C++ utilisez-vous? VC++ 2008 liste toujours les types impliqués pour moi. –

2

Utilisation stringstream (défini dans l'en-tête sstream) pour composer le message d'erreur:

std::stringstream ss; 
ss << "we did " << a_uint << " and got " << result; 
throw std::runtime_error(ss.str()); 
0

Pour un std::string, vous ne pouvez ajouter d'autres std::string s, texte ASCIIZ à une adresse spécifiée par une const char* et individuelle char-characters.

Pour concaténer d'autres types, vous pouvez:

  • utiliser un flux:

    std :: ostringstream oss; oss < < < < a_uint < < "et obtenu" < < résultat; lancer std :: runtime_error (oss.str());

  • le convertir d'abord à une représentation de chaîne:

    jet std :: runtime_error (std :: string ("nous avons fait ") + boost :: lexical_cast (a_uint) + " et obtenu" + boost :: lexical_cast (résultat));

Vous pourriez raisonnablement se demander pourquoi C++ ne fournit pas operator+(std::string&, X&) pour X {short, int, long, long long, float, double, etc. court non signé}, ou même:

template <typename T> 
std::string operator+(std::string& s, T& t) 
{ 
    std::ostringstream oss; 
    oss << t; 
    return s + oss.str(); 
} 

Dans de nombreux cas, ce serait pratique. Mais les flux sont plus puissants car vous pouvez régler la largeur et le caractère de remplissage, la précision du point flottant, etc. En outre, char est le type entier de 8 bits, alors comment le compilateur peut-il ajouter un seul caractère avec cette valeur ASCII? 'A' pour 65), ou une représentation ASCII de la valeur numérique ASCII "65"? (Actuellement, il ne gère pas les ints, donc le traiter comme un seul ASCII char n'est pas déroutant). Ou devrait-il fonctionner pour> = 16 bits mais pas 8? Cela rendrait impossible de redimensionner des variables de/vers des entiers 8 bits sans avoir à faire une analyse d'impact complexe pour voir quelles opérations de chaînes devaient être réécrites. Il est également recommandé de minimiser les dépendances: un pourcentage faible mais peut-être significatif d'unités de traduction utilisant la chaîne ne doit pas nécessairement inclure (et donc passer l'analyse syntaxique) (et par conséquent ostream), et en général les dépendances cycliques sont une "odeur de code" et frustration testabilité (la chaîne dépend de ostringstream dépend de la chaîne ...).