Почему следующий код с неконстантной функцией преобразования не является неоднозначным? - PullRequest
0 голосов
/ 10 октября 2018

Рассмотрим следующий код (взят из https://en.cppreference.com/w/cpp/language/cast_operator)

struct To {
    To() = default;
    To(const struct From&) {} // converting constructor
};

struct From {
    operator To() const {return To();} // conversion function
};

int main()
{
    From f;

    To t2 = f; // copy-initialization: ambiguous
// (note, if conversion function is from a non-const type, e.g.
//  From::operator To();, it will be selected instead of the ctor in this case)
}

. Как отмечается в комментариях, следующая строка действительно неоднозначна, поскольку есть два кандидата (функция преобразования и конструктор преобразования одинаково применимы)

To t2 = f; //compile error

Однако, как сказано в примечании, если я уберу const из функции conversion, получится следующий код:

struct From {
    operator To() {return To();} // conversion function
};

Вызов скомпилируется нормально.
Квалификатор const не должен влиять на возвращаемое значение функции conversion, так почему вызов больше не является двусмысленным?

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Спецификатор const не должен влиять на возвращаемое значение функции преобразования

Это действительно не влияет, но это также не имеет значения.

Что это влияетэто аргумент, который является неявной ссылкой на this.Неявный аргумент является константным значением для константных функций-членов и неконстантным для неконстантных функций-членов.Аргументы - это то, что влияет на разрешение перегрузки.

В исходном коде аргументы как конструктора, так и оператора преобразования одинаковы, поэтому последовательность преобразования из любого типа в любой из аргументов одинаково предпочтительна и, следовательно, неоднозначна.

Безconst, ваше неконстантное выражение lvalue f не требует каких-либо преобразований, в то время как конструктор требует преобразования в const lvalue.Таким образом, оператор предпочитает разрешение перегрузки.Если бы вы написали const From f;, тогда вместо этого был бы выбран конструктор с аргументом const, так как в этом случае оператор неконстантного преобразования даже не был бы допустимым кандидатом.

0 голосов
/ 10 октября 2018

Спецификатор const не должен влиять на возвращаемое значение функции преобразования, так почему вызов больше не является неоднозначным?

Не влияет на результат, но влияет на разрешение перегрузки при выборелучший жизнеспособный метод.Это похоже на случай этих составных функций

To make(From const&);
To make(From&);

Какая перегрузка лучше подходит для make(f)?Это второй, потому что тип параметра, будучи неконстантным, лучше соответствует аргументу (f), который сам не является константным.

...