Почему это не делает неявное приведение к конструктору преобразования? - PullRequest
0 голосов
/ 18 мая 2018

Итак, у меня есть этот код:

struct Foo {
    Foo() { cout << "default\n"; }
    Foo(const long long) { cout << "implicit\n"; }
};

struct Bar {
    Bar(const short param) : param(param) {}
    operator long long() const { return static_cast<long long>(param); }
    const short param;
};

Я бы подумал, что Foo foo = Bar(13) использовал бы мое неявное приведение, а затем конструктор преобразования. Но это ошибки :

ошибка: преобразование из Bar в нескалярный тип Foo запрашивается

Это работает нормально, хотя: Foo foo(Bar(13)).Почему мое неявное приведение используется для явного преобразования, но не для неявного преобразования?

Правила, которые я получил от https://en.cppreference.com/w/cpp/language/copy_initialization, говорят:

Результатпреобразование, которое является выражением prvalue, если использовался конструктор преобразования, затем используется для прямой инициализации объекта

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Поскольку вы используете инициализацию копирования, то в соответствии с документацией

Кроме того, неявное преобразование при инициализации копирования должно производить T непосредственно из инициализатора в то время как, например, прямая инициализация ожидает неявного преобразования инициализатора в аргумент конструктора Т.

Акцент мой.Это не тот случай.

0 голосов
/ 18 мая 2018

Во-первых, неявное преобразование из Bar в long long и преобразование из long long в Foo определяются пользователем.

Foo foo = Bar(13); выполнить копировать инициализацию , компилятор попытается неявно преобразовать Bar в Foo.Требуются два неявных преобразования: преобразование Bar в long long и последующее преобразование long long в Foo.Но только одно пользовательское преобразование разрешено в одной последовательности неявного преобразования .

Последовательность неявного преобразования состоит из следующего в следующем порядке:

1)ноль или одна стандартная последовательность преобразования;

2) ноль или одно пользовательское преобразование;

3) ноль или одна стандартная последовательность преобразования.

пользовательское преобразование состоитнуля или одного неявного конструктора с одним аргументом или неявного вызова функции преобразования

Foo foo(Bar(13)); выполняет прямую инициализацию .Конструкторы Foo будут проверены, и наилучшее совпадение будет выбрано по разрешению перегрузки.Требуется только одно неявное пользовательское преобразование (от Bar до long long);после этого Foo::Foo(long long) вызывается для непосредственного построения foo.

...