2008-10-07 143 views
159

是否有任何很好的理由,一个空的圆括号(圆括号)无效在C++中调用默认的构造函数?默认构造函数与空括号

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

MyObject object(); // error 

我似乎每次都会自动输入“()”。这是不是有很好的理由?

+0

有人应该想出一个更好的标题,但我想不出会是什么。至少拼出“构造函数”来帮助搜索引擎。 – 2008-10-08 05:18:20

+1

这是C++对上下文敏感的另一个很好的例子。如果`blah`是一个类,问题中的示例代码也会失败。 – Albert 2010-08-27 21:03:10

回答

131

最棘手的解析

这与所谓的“C++的最棘手的解析”。基本上,任何可以被编译器解释为声明的东西都会被解释为声明。

同样的问题的另一实例:

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>()); 

或者,如果你有C++ 11和列表初始化(也称为统一初始化)可供选择:

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

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

+0

我已经阅读有效的STL,但我不记得看到这一点。我将不得不再次阅读它,谢谢 – 2008-10-08 16:19:44

+6

Nitpick:你可以在函数内声明函数。它在C中被称为_local functions_,并且在C++中也至少允许`extern“C”foo();`-style。 – 2009-08-08 10:20:30

50

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

+1

谢谢 - 我不会在其他代码中声明一个函数。但我认为这是合法的。 – 2008-10-07 20:36:41

10

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

81

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

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

我其实更喜欢这个例外的答案,它是一个更清晰的问题是什么原因 – thecoshman 2012-10-10 13:17:56

4

我想,编译器会不知道这样的说法:

myObject的对象();

是一个构造函数调用或函数原型声明名为对象返回类型为为MyObject并没有参数的功能。

4

正如多次提到的那样,这是一个声明。这是为了向后兼容。 C++的许多领域之一,因其遗留问题而变得愚蠢/不一致/痛苦/虚假。

7

您还可以使用结构的更详细的方法:

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

在C++ 0x中,这也使得auto

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

从n4296 [DCL。INIT]:

[注:
由于()不是由语法初始化允许的, X a();不是类X的对象的声明,但 声明一个功能的不带参数并返回一个X. form()在某些其他初始化上下文中是允许的(5.3.4, 5.2.3,12.6.2)。
- 完注意事项]

0

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

Jedi luke{}; //default constructor