views:

795

answers:

7

Is there any good reason that an empty set of brackets isn't valid for calling the default ctor in c++?

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

MyObject  object();  // error

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

+28  A: 

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

Nemanja Trifunovic
Thanks - it wouldn't occur to me to declare a function in th emiddle of some other code. But I suppose it is legal.
Martin Beckett
+3  A: 

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

Fred Larson
+11  A: 

Because it is the treated as the declaration for a function:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
1800 INFORMATION
+2  A: 

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.

Black
+2  A: 

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.

Michael Burr
+13  A: 

Most vexing parse

This is known as "C++'s most vexing parse". Basically, anything that can be interpreted by compiler as function declaration will be interpreted as function declaration, even if resulting AST doesn't compile.

Another instance of the same problem:

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

v is interpreted as a declaration of function with 2 parameters and fails to compile.

The workaround is to add another pair of parentheses:

std::vector v((std::istream_iterator(ifs)), std::istream_iterator());
Constantin
I had read Effective STL but I didn't remember seeing that. i will have to read it again, thanks
Martin Beckett
Nitpick: you _can_ declare functions inside functions. It's called _local functions_ in C, and at least `extern "C" foo();`-style is also allowed in C++.
Thanks, mmutz, don't know what i was thinking when i wrote it, probably confused declaration with definition. Edited the answer accordingly.
Constantin
How can that be interpreted as a function?
Casebash
@Casebash, `std::vector` is return type; `v` is function name; `(` opens formal argument list; `std::istream_iterator` is type of first argument; `ifs` is name of first argument, `()` around `ifs` are effectively ignored; second `std::istream_iterator` is type of second argument, which is unnamed, `()` around it are also ignored; ');' closes argument list and function declaration.
Constantin
+1  A: 

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);
dalle
This requires a copy constructor and is inefficient
Casebash
@Casebash: The compiler is probably smart enough to use some `RVO`-like optimization prevent it from being inefficient.
dalle