在c++中,空的圆括号(圆括号)对于调用默认构造函数无效,有什么好的理由吗?

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

MyObject  object();  // error

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


当前回答

最恼人的解析

这与所谓的“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>{}};

这样,就无法将其解释为函数声明。

其他回答

最恼人的解析

这与所谓的“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

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

正如其他人所说,它是一个函数声明。从c++ 11开始,你可以使用大括号初始化,如果你需要看到显式地告诉你使用默认构造函数的空值。

Jedi luke{}; //default constructor

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

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