Любопытство конструктора по умолчанию
В то время как
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()};
)