Je rencontre une énigme épineuse dans mon code de base. Je ne peux pas vraiment dire pourquoi mon code génère cette erreur, mais (par exemple) std :: string ne le fait pas.L'ambiguïté de surcharge d'addition C++
class String {
public:
String(const char*str);
friend String operator+ (const String& lval, const char *rval);
friend String operator+ (const char *lval, const String& rval);
String operator+ (const String& rval);
};
La mise en œuvre de ceux-ci est assez facile à imaginer par vous-même.
Mon programme pilote contient les éléments suivants:
String result, lval("left side "), rval("of string");
char lv[] = "right side ", rv[] = "of string";
result = lv + rval;
printf(result);
result = (lval + rv);
printf(result);
qui génère l'erreur suivante dans gcc 4.1.2:
driver.cpp:25: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
String.h:22: note: candidate 1: String operator+(const String&, const char*)
String.h:24: note: candidate 2: String String::operator+(const String&)
So far so good, non? Malheureusement, mon constructeur String (const char * str) est si pratique à avoir en tant que constructeur implicite, que l'utilisation du mot-clé explicite pour résoudre cela provoquerait simplement une pile différente de problèmes.
De plus ... std :: string n'a pas à recourir à cela, et je n'arrive pas à comprendre pourquoi. Par exemple, dans basic_string.h, ils sont déclarés comme suit:
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT,_Traits,_Alloc>
operator+(const _CharT* __lhs,
const basic_string<_CharT,_Traits,_Alloc>& __rhs);
et ainsi de suite. Le constructeur basic_string n'est pas déclaré explicite. Comment cela ne provoque pas la même erreur que moi, et comment puis-je obtenir le même comportement?
Il ne m'a même pas traversé l'esprit que la constance serait cause d'un mauvais match. Vous et UncleBens étiez (bien sûr) exactement raison. Une autre solution consisterait en fait à faire du membre un non-membre qui accepte deux chaînes const - c'est en fait pourquoi la version std :: string n'a pas d'erreur. Bien sûr, cela équivaut à votre première suggestion, juste écrit différemment. – Nate