C++ 带空括号的默认构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/180172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:28:54  来源:igfitidea点击:

Default constructor with empty brackets

c++constructordefault-constructorc++-faqmost-vexing-parse

提问by Martin Beckett

Is there any good reason that an empty set of round brackets (parentheses) isn't valid for calling the default constructor in C++?

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

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

MyObject  object();  // error

I seem to type "()" automatically everytime. Is there a good reason this isn't allowed?

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

采纳答案by Constantin

Most vexing parse

最烦人的解析

This is related to what is known as "C++'s most vexing parse". Basically, anything that can be interpreted by the compiler as a function declaration will be interpreted as a function declaration.

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

Another instance of the same problem:

同样问题的另一个例子:

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

vis interpreted as a declaration of function with 2 parameters.

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

The workaround is to add another pair of parentheses:

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

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

Or, if you have C++11 and list-initialization (also known as uniform initialization) available:

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

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

With this, there is no way it could be interpreted as a function declaration.

有了这个,就无法将其解释为函数声明。

回答by 1800 INFORMATION

Because it is treated as the declaration for a function:

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

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

回答by Nemanja Trifunovic

The same syntax is used for function declaration - e.g. the function object, taking no parameters and returning MyObject

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

回答by Fred Larson

Because the compiler thinks it is a declaration of a function that takes no arguments and returns a MyObject instance.

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

回答by dalle

You could also use the more verbose way of construction:

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

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

In C++0x this also allows for auto:

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

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

回答by Black

I guess, the compiler would not know if this statement:

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

MyObject object();

MyObject 对象();

is a constructor call or a function prototype declaring a function named objectwith return type MyObjectand no parameters.

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

回答by Michael Burr

As mentioned many times, it's a declaration. It's that way for backward compatibility. One of the many areas of C++ that are goofy/inconsistent/painful/bogus because of its legacy.

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

回答by Andreas DM

From n4296 [dcl.init]:

来自 n4296 [dcl.init]:

[ Note:
Since ()is not permitted by the syntax for initializer, X a();is not the declaration of an objectof class X, but the declaration of a functiontaking no argument and returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2).
—end note ]

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

C++11 Link
C++14 Link

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

回答by Hitokage

As the others said, it is a function declaration. Since C++11 you can use brace initialization if you need to see the empty somethingthat explicitly tells you that a default constructor is used.

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

Jedi luke{}; //default constructor