Подтвердить что ты не робот

Приоритет перегруженных операторов

В приведенном ниже коде я ожидал бы получить ошибку компилятора, если из-за неоднозначности определено несколько операторов-операторов.

#include <iostream>
#include <sstream>

struct A
{
    operator const char*() { return "hello world\n"; }
    operator float()       { return 123.0F; }
    //operator int()         { return 49; }
};

int main()
{
    A a;
    std::stringstream ss;
    ss << a;
    std::cout << ss.str();
    return 0;
}

Вместо этого, если определен только один оператор с числовым литьем, он компилируется без ошибок, без предупреждений, а числовое преобразование используется в предпочтении operator const char *(). Порядок заявленных операторов не имеет значения.

Однако, если operator int() и operator float() оба определены, я получаю то, что я ожидал с самого начала:

'< < неоднозначно

Существуют ли правила приоритета для кастомий или почему компилятор выбирает числовое значение по умолчанию? Я понимаю, что я должен явно указать, какое действие я имею в виду, но мой вопрос касается выбора по умолчанию, который делает компилятор.


Изменить: использование компилятора MSVC 2010
4b9b3361

Ответ 1

Конверсии ранжируются в соответствии с § 13.3.3.1 Стандарта С++. В частности, пользовательские последовательности преобразований, относящиеся к вашему примеру, регулируются § 13.3.3.1.2/1:

"Пользовательская последовательность преобразований состоит из начальной стандартной последовательности преобразования, за которой следует пользовательское преобразование (12.3), за которым следует вторая стандартная последовательность преобразования. [...] Если пользовательское преобразование задается (12.3.2), начальная стандартная последовательность преобразования преобразует тип источника в неявный параметр объекта функции преобразования."

Все последовательности преобразований включают в себя:

  • фиктивное преобразование в тип источника неявного параметра объекта функции преобразования;
  • пользовательское преобразование;
  • преобразование идентичности в тип ввода operator <<.

Эти последовательности преобразования имеют одинаковый ранг. Таким образом, вызов должен быть неоднозначным. Если это не так, для меня это ошибка компилятора.