Categories
c++ c++-faq constructor default-constructor most-vexing-parse

Default constructor with empty brackets

219

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?

3

  • Someone should come up with a better title for this, but I can’t think of what that would be. At least spell out “constructor” to help the search engine(s).

    – Adam Mitz

    Oct 8, 2008 at 5:18

  • 1

    And this is just another good example where C++ is context sensitive. The example code in the question would also fail if blah would be a class.

    – Albert

    Aug 27, 2010 at 21:03

  • One thing that I noticed is that if I only have the default constructor then the compiler doesn’t give any error if I use () e.g. MyObject object works as usual & MyObject object() does not give any error! Could someone please explain why? I mean I haven’t defined the function in my main… so it should give an error, right? Thanks in advance!

    – Milan

    Nov 12, 2020 at 0:04

181

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.

11

  • 7

    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++.

    Aug 8, 2009 at 10:20

  • 4

    How can that be interpreted as a function?

    – Casebash

    Oct 29, 2010 at 1:00

  • 14

    @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.

    Oct 30, 2010 at 7:31


  • 2

    There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration. (C++ ISO/IEC (2003) 6.8.1)

    Sep 28, 2012 at 9:12

  • 12

    @Constantin, the parentheses after the second argument are not ignored. The second parameter is not a std::istream_iterator but a pointer/reference to a function that takes no arguments and returns an istream_iterator.

    – CTMacUser

    Feb 15, 2014 at 0:25

119

Because it is treated as the declaration for a function:

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

3

  • But it should give an error, right? Because we haven’t defined the object() function right? Could you please elaborate on that? I’m confused right now. Thank you so much in advance!

    – Milan

    Nov 12, 2020 at 0:07

  • On a side note, in my main, I even tried these: any_variable_name random_function_name() e.g. int func1() , double func2(), void func3(), etc. and all of them works i.e. my program gets compiled without any error! However, I haven’t defined any of those functions, so, I should get errors, right?

    – Milan

    Nov 12, 2020 at 0:13


  • 1

    @Milan I would expect linker errors if you actually tried to call those functions. Otherwise they are just declarations

    Nov 15, 2020 at 22:31

51

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

1

  • 2

    Thanks – it wouldn’t occur to me to declare a function in th emiddle of some other code. But I suppose it is legal.

    Oct 7, 2008 at 20:36