Любопытство конструктора по умолчанию

В то время как

MyClass m();

это классическая ошибка, так как она не объявляет переменную m, а функцию принимает нулевые аргументы и возвращает MyClass. Тем не менее, я обнаружил, что в Visual Studio следующий оператор создает ту же проблему (кажется, что это как-то сводится к приведенному выше утверждению):

MyClass m( MyClass() );

Кто-нибудь может объяснить это поведение?

Примечание: более "явная" версия того, что ожидается, делает правильные вещи (то есть вызывает по умолчанию, а не конструктор перемещения).

MyClass m( std::move( MyClass() ) );

2 ответа

Решение

Это самая сложная проблема Parse.

MyClass m( MyClass() );

Эта строка анализируется как функция с именем m, возвращающая объект типа MyClass и принимающая единственный аргумент, который является указателем на функцию без аргументов и возвращаемое значение типа MyClass.

Вот:

MyClass m( std::move( MyClass() ) );

std:: move помогает компилятору анализировать строку, как и ожидалось.

Да, это классический Most Vexing Parse. Все, что выглядит как функция, является функцией, даже если это может быть что-то еще.

Есть несколько устаревших методов, чтобы перевести это в правильное определение переменной, но лучше всего использовать равномерную инициализацию:

MyClass m{MyClass()};

(Несмотря на тот факт, что приведенный выше пример является избыточным, и лучшим примером будет случай, когда типы различаются, например, A m{B()};)

Другие вопросы по тегам