Object instantiation gets parsed as func.def.?

  • Thread starter Thread starter Agoston Bejo
  • Start date Start date
A

Agoston Bejo

Hi! This is the smallest example I was able to create to demonstratet the
problem. It seems that a certain kind of object instantiation gets parsed as
a function definition (or whatever) by the compiler. I don't know if it
comes from some (maybe not-so-)dark corner of the C++ standard, or VC7.1 has
got a bug.

Thx,
Agoston

//-----------------------------------
template<typename T>
struct A {
A(T t):t(t) {}
T t;
};

template<typename T> void f()
{
cout << T() << endl;
A<T> a1((T()));
A<T> a2(T()); // function definition?
cout << a1.t << endl;
cout << a2.t << endl; // compile error! (*)
}

int _tmain(int argc, _TCHAR* argv[])
{
f<int>();
return 0;
}

// (*) error message:
// error C2228: left of '.t' must have class/struct/union type
// type is 'overloaded-function'
// see reference to function template instantiation
// 'void f<int>(void)' being compiled

//--------------------------------------------
 
Agoston said:
Hi! This is the smallest example I was able to create to demonstratet the
problem. It seems that a certain kind of object instantiation gets parsed as
a function definition (or whatever) by the compiler. I don't know if it
comes from some (maybe not-so-)dark corner of the C++ standard, or VC7.1 has
got a bug.

The "dark corner" theory is correct.
Thx,
Agoston

//-----------------------------------
template<typename T>
struct A {
A(T t):t(t) {}
T t;
};

template<typename T> void f()
{
cout << T() << endl;
A<T> a1((T()));
A<T> a2(T()); // function definition?
cout << a1.t << endl;
cout << a2.t << endl; // compile error! (*)
}

int _tmain(int argc, _TCHAR* argv[])
{
f<int>();
return 0;
}

// (*) error message:
// error C2228: left of '.t' must have class/struct/union type
// type is 'overloaded-function'
// see reference to function template instantiation
// 'void f<int>(void)' being compiled

//--------------------------------------------

VC is correct. This is what Scott Meyers described as a "vexing parse" in
"Effective STL". To simplify:

int f(int());

This declares a function f that has one parameter of the type:

int (*)();

That is, the parameter is unnamed and has type "pointer to a function that
has no parameters and returns int".

You've already discovered one way to get the effect you're after, namely
parenthesizing the ctor argument.
 
Back
Top