Вопрос: Неоднозначная перегрузка для оператора + с использованием преобразования


У меня класс с конверсиями konw -> int, double -> konw:

class konw {
    double re, im;
public:
    konw() : re(0.0), im(0.0) {}
    konw(double r, double i = 0.0) : re(r), im(i) {}
    operator int() {return re;}
    konw operator+(konw a) {konw wynik; wynik.re = re + a.re; wynik.im = im + a.im; return wynik;}
};

В основном я тестирую эти преобразования с помощью перегруженного оператора +

konw zesp(3.1, 0.6);
int ssuma = zesp + 6;

Компилятор сообщает об ошибке при работе над последней прикрепленной строкой, в которой говорится:

ambiguous overload for 'operator+' in 'zesp + 6'

Насколько я читал, если есть несколько способов вызова перегруженной функции, компилятор выбирает самый короткий. Конечно, должен быть один и только такой способ. Я мог бы найти два способа вызова оператора +:

  1. переменная преобразования zesp konw -> int и вызов operator+(int, int)
  2. константа преобразования 6 int-> double-> konw и вызов konw::operator+(konw)

1-й метод быстрее, чем 2-й, поэтому Imo компилятор должен выбрать его и выполнить, но в нем указывается ошибка об неоднозначной перегрузке. Зачем? Где ошибка в моем процессе мышления?


4


источник


Ответы:


Выбор не является «кратчайшей» или «самой быстрой» последовательностью преобразования. Правила довольно сложны ( [ovr.ics.rank] в стандарте), но в этом случае обе последовательности преобразования требуют пользовательского преобразования, поэтому они являются «определяемыми пользователем последовательностями преобразования» и считаются одинаково хорошими. Дополнительное встроенное преобразование во втором случае не делает его хуже.


4



Ваш компилятор говорит вам следующее:

int ssuma = zesp + 6;
                   ^
prog.cpp:15:19: note: candidates are:
prog.cpp:15:19: note: operator+(int, int) <built-in>
prog.cpp:10:10: note: konw konw::operator+(konw)

потому что весь ваш компилятор видит:

  • «Эй, подожди, есть zesp + 6, может быть, я должен использовать konw::operator+ и конвертировать 6 в konw объект»
  • «Подожди, я тоже могу конвертировать zesp в int и использовать встроенный operator+(int, int)"

Поэтому вы должны явно указать компилятору, какой из них использовать:

int ssuma = int(zesp) + 6;

2