Нет ли скобок в конструкторе без аргументов в качестве языка?

Я компилировал С++-программу в Cygwin, используя g++, и у меня был класс, у конструктора которого нет аргументов. У меня были строки:

MyClass myObj();
myObj.function1();

И при попытке скомпилировать его я получил сообщение:

error: запрос для члена 'function1' в 'myObj', который относится к классу non-class 'MyClass()()'

После небольшого исследования я обнаружил, что исправить было изменение этой первой строки на   MyClass myObj;

Я мог бы поклясться, что раньше я делал пустые объявления конструкторов с круглыми скобками на С++. Возможно, это ограничение компилятора, который я использую, или действительно говорит о стандарте языка, не используйте круглые скобки для конструктора без аргументов?

Ответ 1

Хотя MyClass myObj(); можно проанализировать как определение объекта с пустым инициализатором или объявлением функции, в стандарте языка указывается, что неоднозначность всегда разрешается в пользу объявления функции. Пустой инициализатор круглых скобок допускается в других контекстах, например. в выражении new или при создании инициализированного значения.

Ответ 2

Это называется самой неприятной проблемой синтаксического анализа. Когда синтаксический анализатор видит

MyClass myObj();

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

Чтобы обойти это, используйте:

MyClass myObj;

Ответ 3

Я нашел это в стандарте С++ (§8.5.8):

Объект, инициализатор которого представляет собой пустой набор скобок, т.е.(), должен инициализироваться значением.

[Примечание: поскольку() не разрешено синтаксис инициализатора,

X a ();

не является объявлением объекта класса X, но объявление функции, не принимающей аргументом и возвратом X. Форма () разрешено в некоторых других контексты инициализации (5.3.4, 5.2.3, 12.6.2). -end note]

Ответ 4

Это довольно хорошо известная проблема и не зависит от компилятора. По существу, вы делали объявление функции, возвращающей тип MyObj. Неудивительно, что вы не можете вызвать его конструктор. См. С++ faq lite для хорошего объяснения

Ответ 6

MyClass myObj();

Это анализируется как объявление функции, функция называется myObj, не принимает аргументов и возвращает объект MyClass. Я никогда не видел, чтобы компилятор это принимал. С другой стороны, MyClass* myPtr = new MyClass(); приемлемо, может быть, вы путаете?

Ответ 7

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

Ответ 8

Стандарт не требует скобок.

int* x = new int;

является юридическим синтаксисом.

В вашем случае myclass myobj(); является прототипом функции. В то время как myclass myobj; является переменной.