3

Possible Duplicate:
Error on calling default constructor with empty set of brackets

Why does the following code compile without problems but when I switch the line

MCl<char, a> tryout;

to

MCl<char, a> tryout();

I receive "error C2228: left of '.ea' must have class/struct/union" ? Isn't tryout() a call to the default constructor?

Here's the full code

template <class T, T myval> class MCl
{
public:
    T ea;
    MCl() : ea(myval)
    {
    }
};

int main()
{


    const char a = 'e';
    MCl<char, a> tryout;
    // MCl<char, a> tryout();

    cout << tryout.ea;

    return 0;
}
Community
  • 1
  • 1
Johnny Pauling
  • 12,701
  • 18
  • 65
  • 108
  • 2
    See [most vexing parse](http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work). – DCoder Oct 06 '12 at 11:52

3 Answers3

4
MCl<char, a> tryout();

declares function tryout, that receives nothing and returns MCl<char, a>.

n3337 8.2/1

the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in 6.8, the resolution is to consider any construct that could possibly be a declaration a declaration. [ Note: A declaration can be explicitly disambiguated by a nonfunction-style cast, by an = to indicate initialization or by removing the redundant parentheses around the parameter name. —end note ]

ForEveR
  • 55,233
  • 2
  • 119
  • 133
4
MCl<char, a> tryout();

This is ambiguous as either a function prototype or instantiation through a void constructor. This ambiguity has been covered to death as 'the most vexing parse' - it is even discussed in the C++03 standard itself!

However, people tend not to mention that C++11 introduces a new syntax to disambiguate this through uniform initialization. Under this new syntax, your instantiation of MCl would be expressed as so:

MCl<char, a> tryout{};
Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
0

Declares a variables;

MCl<char, a> tryout;    // uses default constructor if user defined one.
                        // If compiler generated constructor uses value-initialized
                        // of members which for POD types means uninitialized.

Is a forward declaration to a function (called tryout):

MCl<char, a> tryout();

What you wanted was probably: (for C++03 for C++11 see Mike Kwan).

MCl<char, a> tryout  = MCl<char, a>(); // uses default constructor if user defined one.
                        // If compiler generated constructor uses zero-initialized
                        // of members which for POD types means 0 is placed in them.
Martin York
  • 257,169
  • 86
  • 333
  • 562