217

是否有充分的理由表明一组空的圆括号(括号)对于调用 C++ 中的默认构造函数无效?

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

MyObject  object();  // error

我似乎每次都自动输入“()”。有充分的理由不允许这样做吗?

4

9 回答 9

180

最烦人的解析

这与所谓的“C++ 最令人头疼的解析”有关。基本上,任何可以被编译器解释为函数声明的东西都将被解释为函数声明。

同样问题的另一个例子:

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

v被解释为带有 2 个参数的函数声明。

解决方法是添加另一对括号:

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

或者,如果您有可用的 C++11 和列表初始化(也称为统一初始化):

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

有了这个,它就不可能被解释为一个函数声明。

于 2008-10-08T05:30:31.543 回答
118

因为它被视为函数的声明:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
于 2008-10-07T20:15:41.303 回答
51

函数声明使用相同的语法-例如函数object,不带参数并返回MyObject

于 2008-10-07T20:15:22.163 回答
11

因为编译器认为它是一个不带参数并返回 MyObject 实例的函数的声明。

于 2008-10-07T20:15:25.690 回答
8

您还可以使用更详细的构造方式:

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

在 C++0x 中,这也允许auto

auto object1 = MyObject();
auto object2 = MyObject(object1);
于 2008-10-08T08:05:08.767 回答
7

我猜,编译器不知道这个语句是否:

我的对象对象();

是一个构造函数调用或函数原型,它声明了一个名为object的函数,返回类型为MyObject且没有参数。

于 2008-10-07T20:17:11.147 回答
5

正如多次提到的,这是一个声明。这是向后兼容的方式。由于其遗留问题,C++ 的许多愚蠢/不一致/痛苦/虚假的领域之一。

于 2008-10-07T21:34:19.867 回答
5

从 n4296 [dcl.init]:

[注意:
由于initializer()的语法不允许, 因此不是类 X的对象的声明,而是不带参数并返回 X 的函数的声明。在某些其他初始化上下文中允许使用 () 形式( 5.3.4、5.2.3、12.6.2)。 ——尾注]X a();

C++11 链接
C++14 链接

于 2015-06-27T20:09:36.853 回答
3

正如其他人所说,它是一个函数声明。从 C++11 开始,如果您需要查看明确告诉您使用默认构造函数的空内容,则可以使用大括号初始化。

Jedi luke{}; //default constructor
于 2017-10-19T07:11:57.337 回答