带空括号的默认构造函数
-
05-07-2019 - |
题
有一个空的圆括号(圆括号)对于在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
被解释为具有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>{}};
有了这个,就无法将其解释为函数声明。
其他提示
因为它被视为函数的声明:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
相同的语法用于函数声明 - 例如函数 object
,不带参数并返回 MyObject
因为编译器认为它是函数的声明,它不带参数并返回MyObject实例。
我猜,编译器不会知道这句话是否是:
MyObject object();
是一个构造函数调用或函数原型,声明一个名为 object 的函数,返回类型为 MyObject 且没有参数。
你也可以使用更详细的构造方式:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
在C ++ 0x中,这也允许 auto
:
auto object1 = MyObject();
auto object2 = MyObject(object1);
如上所述,这是一个宣言。这是向后兼容的方式。 C ++的许多领域之一,由于其遗留问题而愚蠢/不一致/痛苦/虚假。
来自n4296 [dcl.init]:
[注意:由于初始值设定项的语法不允许
()
,X a();
不是X类的对象的声明,但是 声明函数不带参数并返回X. 在某些其他初始化上下文中允许使用form()(5.3.4, 5.2.3,12.6.2)。
&#8212;结束说明]
正如其他人所说,这是一个功能声明。从C ++ 11开始,你可以使用大括号初始化,如果你需要看到空的某些东西明确地告诉你使用了一个默认的构造函数。
Jedi luke{}; //default constructor