Какую функцию преобразования следует вызвать в следующем примере? Почему следует предпочесть одно другому?
struct A
{
operator int();
operator int*();
};
A x;
int i = x + 1;
Компилятор выбирает operator int() .. но почему?
Вот некоторые актуальные цитаты из C ++ 03:
От [expr.add]
В качестве дополнения, оба операнда должны иметь арифметический или перечислительный тип, или один операнд должен быть указателем на полностью определенный тип объекта, а другой должен иметь целочисленный или перечисляемый тип.
От [конв.]
выражения с заданным типом будут неявно преобразованы в другие типы в нескольких контекстах:
- При использовании в качестве операндов операторов. Требования оператора к его операндам диктуют тип назначения.
Ответ 1 · рейтинг 9 · Andy Prowl
Причина такого поведения в том, что встроенный оператор, который принимает указатель в качестве своего левого операнда, принимает объект типа std::ptrdiff_t в качестве своего правого операнда. Это указано в § 13.6 стандарта C ++ 11:
Для каждого cv-квалифицированного или cv-неквалифицированного типа объекта T существуют кандидатные операторные функции вида
T * operator+(T *, std::ptrdiff_t);
[...]
Поскольку 1 имеет тип int, компилятор рассматривает встроенный operator +, который принимает два int, как лучший выбор, потому что для него требуется только (определяемое пользователем) преобразование для первого аргумента.
Если вы предоставили аргумент типа std::ptrdiff_t как правый операнд operator +, вы увидите ожидаемую двусмысленность:
int i = x + static_cast<std::ptrdiff_t>(1); // AMBIGUOUS!
Вот живой пример.