在c++中,空的圆括号(圆括号)对于调用默认构造函数无效,有什么好的理由吗?
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
我似乎每次都会自动输入“()”。有什么理由不允许这样做吗?
在c++中,空的圆括号(圆括号)对于调用默认构造函数无效,有什么好的理由吗?
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
我似乎每次都会自动输入“()”。有什么理由不允许这样做吗?
因为它被视为函数的声明:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
我猜,编译器不会知道这个语句:
MyObject object();
是一个构造函数调用或函数原型,声明一个名为object的函数,返回类型为MyObject,不带形参。
最恼人的解析
这与所谓的“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>{}};
这样,就无法将其解释为函数声明。
你也可以使用更详细的构造方式:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
在c++ 0x中,这也允许auto:
auto object1 = MyObject();
auto object2 = MyObject(object1);
从n4296 [dcl.init]:
[注意:由于初始化式语法不允许使用(), X ();不是类X对象的声明,而是 函数不带参数并返回x的声明 Form()在某些其他初始化上下文中被允许(5.3.4, 5.2.3 12.6.2)。 -结束注释]
c++ 11链接 c++ 14链接
正如其他人所说,它是一个函数声明。从c++ 11开始,你可以使用大括号初始化,如果你需要看到显式地告诉你使用默认构造函数的空值。
Jedi luke{}; //default constructor