最恼人的解析错误:没有参数的构造函数

问题描述 投票:0回答:7

我正在使用 g++ 在 Cygwin 中编译一个 C++ 程序,我有一个类的构造函数没有参数。我有台词:

MyClass myObj();
myObj.function1();

在尝试编译它时,我收到消息:

error: request for member 'function1' in 'myObj', which is of non-class type 'MyClass ()()'

经过一番研究,我发现解决方法是将第一行更改为

MyClass myObj;

我可以发誓我以前在 C++ 中做过带括号的空构造函数声明。这可能是我正在使用的编译器的限制,还是语言标准真的说不要对没有参数的构造函数使用括号?

c++ constructor standards
7个回答
63
投票

尽管

MyClass myObj();
可以被解析为具有空初始值设定项或函数声明的对象定义,但语言标准指定歧义始终以有利于函数声明的方式解决。在其他上下文中允许使用空括号初始值设定项,例如在
new
表达式中或构造一个 value-initialized temporary.


58
投票

这被称为Most Vexing Parse问题。当解析器看到

MyClass myObj();

它认为你正在声明一个名为

myObj
的函数,它没有参数并返回一个
MyClass

要绕过它,请使用:

MyClass myObj;

20
投票

我在 C++ 标准(§8.5.8)中找到了这个:

初始化器为空括号集的对象,即 (),应进行值初始化。

[注:因为 () 是不允许的 初始化程序的语法,

X a ();

不是 X 类对象的声明,而是 不带参数的函数声明 参数并返回一个 X. 形式 () 在某些其他情况下是允许的 初始化上下文(5.3.4、5.2.3、 12.6.2). ——尾注]


11
投票

这是一个众所周知的问题,与编译器无关。本质上,您是在声明一个返回类型 MyObj 的函数。毫不奇怪,您不能调用它的构造函数。请参阅 C++ faq lite 以获得很好的解释。


4
投票
MyClass myObj();

这被解析为函数声明。该函数称为 myObj,不带参数并返回一个 MyClass 对象。我从未见过编译器接受它。另一方面,

MyClass* myPtr = new MyClass();
是可以接受的,这可能让您感到困惑吗?


3
投票

你的行让编译器认为你正在声明一个名为

myObj
的函数,它不接受任何参数并返回一个
MyClass
。这种歧义解析确实很烦人


1
投票

标准不需要括号。

int* x = new int;

是合法语法。

在你的例子中

myclass myobj();
是一个函数原型。而
myclass myobj;
是一个变量。

© www.soinside.com 2019 - 2024. All rights reserved.