Default constructor with empty brackets

2018-12-30 23:33发布

Is there any good reason that an empty set of round brackets (parentheses) isn't valid for calling the default constructor in 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?

9条回答
有味是清欢
2楼-- · 2018-12-31 00:02

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.

Another instance of the same problem:

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

v is interpreted as a declaration of function with 2 parameters.

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:

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.

查看更多
牵手、夕阳
3楼-- · 2018-12-31 00:02

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

Jedi luke{}; //default constructor
查看更多
泛滥B
4楼-- · 2018-12-31 00:05

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

查看更多
刘海飞了
5楼-- · 2018-12-31 00:05

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

查看更多
永恒的永恒
6楼-- · 2018-12-31 00:05

From n4296 [dcl.init]:

[ Note:
Since () is not permitted by the syntax for initializer, X a(); is not the declaration of an object of class X, but the declaration of a function taking 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 ]

查看更多
荒废的爱情
7楼-- · 2018-12-31 00:12

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:

auto object1 = MyObject();
auto object2 = MyObject(object1);
查看更多
登录 后发表回答