Default constructor with empty bracketsDefault constructor with empty brackets - Solution Checker - solutionschecker.com - Find the solution for any programming question. We as a solution checker will focus on finding the fastest possible solution for developers. Main topics like coding, learning.

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?

Solution 1

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

Because it is treated as the declaration for a function:

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

Solution 3

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

Solution 4

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

Solution 5

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

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

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

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

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