C ++ 11: Неопределенность между преобразователем конструктора и функцией преобразования при инициализации параметра передачи по значению? - PullRequest
6 голосов
/ 12 марта 2012
#include <iostream>
using namespace std;

struct Y;

struct X
{
    X(const Y&) { cout << "converting constructor" << endl; }
};

struct Y
{
    operator X() { cout << "conversion function" << endl; }
};

void f(X x) {}

int main()
{
    Y y;
    f(y);
}

В приведенном выше описании функции преобразования приоритет отдается конструктору преобразования моим компилятором (gcc 4.6.1), однако в стандарте говорится, что:

Определяемые пользователем преобразования применяются только там, где они однозначны

Казалось бы, в этом случае существует неоднозначность.Может кто-нибудь объяснить противоречие?

Я бы ожидал, что выше не скомпилировать.Я также вполне уверен, что несколько лет назад Скотт Мейерс написал об этом конкретном примере и сказал, что он не будет компилироваться.Чего мне не хватает?

Ответы [ 2 ]

5 голосов
/ 12 марта 2012

Поскольку конструктор X хочет аргумент const, он предпочитает оператор.Если вы удалите const в конструкторе X, компилятор пожалуется на неоднозначность.Если имеется более одной функции с эталонными параметрами, предпочтительнее ту, которая имеет наиболее релевантную квалификацию const.

Хороший ответ здесь

1 голос
/ 12 марта 2012

Здесь нет двусмысленности, единственное действительное преобразование обеспечивается функцией преобразования .
Обратите внимание, что y - это , а не const, ваш конструктор преобразования нуждается в аргументе const.

Была бы двусмысленность, если бы ваш конструктор преобразования использовал неконстантную ссылку.

Образец онлайн:

#include <iostream>
using namespace std;

struct Y;

struct X
{
    X(Y&) { cout << "converting constructor" << endl; }

};

struct Y
{
    operator X() { cout << "conversion function" << endl; }
};

void f(X x) {}

int main()
{
    Y y;
    f(y);
    return 0;  
}

Выход:

prog.cpp: внутри функции-члена ‘Y :: operator X ()’:
prog.cpp: 13: предупреждение: нет оператора возврата в функции, возвращающей не void
prog.cpp: в функции int main ():
prog.cpp: 21: ошибка: преобразование из «Y» в «X» является неоднозначным
prog.cpp: 13: примечание: кандидаты: Y :: operator X ()
prog.cpp: 8: примечание: X :: X (Y &)

...