Я подхожу против досадной головоломки в моей базе кода. Я не могу сказать, почему мой код генерирует эту ошибку, но (например) std :: string не работает.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);
};
Реализация этих средств достаточно проста, чтобы представить себя самостоятельно.
Моя программа драйвера содержит следующее:
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);
который генерирует следующее сообщение об ошибке в 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&)
До сих пор так хорошо, не так ли? К сожалению, мой конструктор String (const char * str) настолько удобен как неявный конструктор, что использование явного ключевого слова для его решения просто вызовет другую проблему.
Кроме того ... std :: string не нужно прибегать к этому, и я не могу понять, почему. Например, в basic_string.h они объявлены следующим образом:
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);
и так далее. Конструктор basic_string не объявляется явно. Как это не вызывает ту же ошибку, которую я получаю, и как я могу достичь такого же поведения?
Мне даже не приходило в голову, что константа будет причиной плохого матча. Вы и UncleBens были (конечно) в точности. Еще одно решение состоит в том, чтобы сделать член нечленом, который принимает две константные строки - на самом деле это почему версия std :: string не имеет ошибки. Конечно, это эквивалентно вашему первому предложению, просто написанному по-разному. – Nate