Default constructor with empty brackets

C++ConstructorDefault ConstructorC++ FaqMost Vexing-Parse

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

Because it is treated as the declaration for a function:

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

Solution 3 - C++

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

Solution 4 - C++

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

Solution 5 - C++

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

> MyObject object();

is a constructor call or a function prototype declaring a function named object with return type MyObject and no parameters.

Solution 6 - C++

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);

Solution 7 - C++

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.

Solution 8 - C++

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 ]

C++11 Link
C++14 Link

Solution 9 - C++

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin BeckettView Question on Stackoverflow
Solution 1 - C++ConstantinView Answer on Stackoverflow
Solution 2 - C++1800 INFORMATIONView Answer on Stackoverflow
Solution 3 - C++Nemanja TrifunovicView Answer on Stackoverflow
Solution 4 - C++Fred LarsonView Answer on Stackoverflow
Solution 5 - C++BlackView Answer on Stackoverflow
Solution 6 - C++dalleView Answer on Stackoverflow
Solution 7 - C++Michael BurrView Answer on Stackoverflow
Solution 8 - C++Andreas DMView Answer on Stackoverflow
Solution 9 - C++HitokageView Answer on Stackoverflow