The following program, compiled with g++ 4.6, yields the error
request for member ‘y’ in ‘a2’, which is of non-class type ‘A<B>(B)’
at its last line:
#include <iostream>
template <class T> class A
{
public:
T y;
A(T x):y(x){}
};
class B
{
public:
int u;
B(int v):u(v){}
};
int main()
{
int v = 10;
B b1(v);
//works
A<B> a1(b1);
//does not work (the error is when a2 is used)
A<B> a2(B(v));
//works
//A<B> a2((B(v)));
std::cout << a1.y.u << " " << a2.y.u << std::endl;
}
As can be seen from the working variant included in the code, adding parentheses around the arguments of the constructor of A solves the problem.
I have seen some related errors caused by a the interpretation of a constructor invocation as a function declaration, like when creating an object with no argument to its constructor, but with braces:
myclass myobj();
but it seems to me that
A<B> a2(B(v));
cannot be interpreted as a function declaration.
Someone can explain to me what is happening?
It's a case of most vexing parse where the compiler interprets A<B> a2(B(v))
as the declaration of a function. Such that:
A<B>
is the return typea2
is the function nameB
is the type of the argumentv
is the argument name
So, when you are doing
std::cout << a1.y.u << " " << a2.y.u << std::endl;
The compiler does not think of a2.y.u
as a class, that's why you are getting the non-class type
error.
Also, since double parenthesis aren't allowed in a function declaration, the version A<B> a2((B(v)));
works because the compiler doesn't interprets it as a function declaration anymore, but as a variable declaration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With