Это продолжение этого вопроса: условное выражение оператора с базовым и константным классом не компилируется, почему?.
Ядро Cond? [cv] t1 (): [cv] t2 () , где, например, t2 публично наследуют от t1 .
Попытка следовать Правила для определения типа выражения, казалось, потребовалось неявную последовательность преобразования из производного объекта в базовый. Тем не менее были действительно просты: < /p>
struct X {};
struct Y : X {};
< /code>
и, таким образом, они имеют неявное перемещение по умолчанию и копирование конструкторов, которые могут позволить сформировать неявную последовательность преобразования. < /p>
Чтобы проверить эту гипотезу, Я попытался объяснить этих операторов, чтобы сломать последовательность преобразования: < /p>
#include
struct X {
X() = default;
explicit X(X const &) { std::cout
gcc < /th>
clang < /th>
msvc < /th>
< /tr>
< /thead>
< tbody>
none < /td>
перейти к базе < /td>
Перейти к базе < /td> перейти к Base < /td>
< /tr>
on Move только < /td>
< Strong> перейти на базу (ожидаемая копия)
копировать на базу
перейти к базе (ожидается копировать) < /td>
< /tr>
только на копирование < /td>
перейти на базу < /td> перейти к Base < /td>
перемещение в Base < /td>
< /tr>
Оба
перейти к базе (ожидаемая ошибка)
ошибка
ошибка
Мое ожидание было: если существует неявный конструктор движения, Используйте его в последовательности преобразования, в противном случае, если существует конструктор копирования, используйте его в последовательности преобразования, в противном случае неявная последовательность преобразования. < /p>
Почему выход отличается от компилятора до Другой, и почему они не соответствуют моим ожиданиям? Больше в соответствии с моими ожиданиями, за исключением MSVC: < /p>
void foo(X) {};
int main() { foo(Y()); }
< /code>
Live
В этом случае только MSVC ведет себя странно, всегда используя оператор движения. Я думаю, что это может быть ошибка MSVC.
Подробнее здесь: https://stackoverflow.com/questions/794 ... ce-used-fo