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

Есть ли веская причина, что пустой набор круглых скобок (скобки) недействителен для вызова конструктора по умолчанию в С++?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error

Кажется, я набираю "()" автоматически каждый раз. Есть ли веская причина, по которой это не разрешено?

Ответ 1

Самый неприятный синтаксический анализ

Это связано с тем, что называется "С++ most vexing parse". В принципе, все, что может быть интерпретировано компилятором как объявлением функции, будет интерпретироваться как объявление функции.

Другой экземпляр той же проблемы:

std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());

v интерпретируется как объявление функции с двумя параметрами.

Обходной путь заключается в добавлении еще одной пары круглых скобок:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());

Или, если у вас есть С++ 11 и инициализация списка (также известная как равномерная инициализация):

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};

При этом нет способа интерпретировать его как объявление функции.

Ответ 2

Потому что он рассматривается как объявление для функции:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration

Ответ 3

Тот же синтаксис используется для объявления функции - например, функция object, не принимающая никаких параметров и возвращающая MyObject

Ответ 4

Поскольку компилятор считает, что это объявление функции, которая не принимает аргументов и возвращает экземпляр MyObject.

Ответ 5

Вы также можете использовать более подробный способ построения:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);

В С++ 0x это также позволяет auto:

auto object1 = MyObject();
auto object2 = MyObject(object1);

Ответ 6

Я думаю, компилятор не знал бы, будет ли это утверждение:

Объект MyObject();

- это вызов конструктора или прототип функции, объявляющий функцию с именем object с возвращаемым типом MyObject и без параметров.

Ответ 7

Как уже упоминалось много раз, это декларация. Это так для обратной совместимости. Одна из многих областей С++, которая является тупой/непоследовательной/болезненной/фиктивной из-за ее наследия.

Ответ 8

От n4296 [dcl.init]:

[Примечание:
Поскольку () не разрешен синтаксисом для инициализатора, X a(); не является объявлением объекта класса X, но объявление функции, не принимающей аргументов и возвращающей X. form() разрешена в некоторых других контекстах инициализации (5.3.4, 5.2.3, 12.6.2).
- конец заметки]

С++ 11 Ссылка
С++ 14 Ссылка

Ответ 9

Как говорили другие, это объявление функции. Начиная с С++ 11 вы можете использовать инициализацию скобки, если вам нужно увидеть пустое то, что явно указывает вам, что используется конструктор по умолчанию.

Jedi luke{}; //default constructor