问题
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?
回答1:
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.
回答2:
I think you're getting bit by the "most vexing parse", meaning that A<B> a2(B(v));
is getting parsed as function declaration instead of a variable declaration.
回答3:
It is a function declaration:
A<B> a2(B(v));
//is same as:
A<B> a2(B v);
//consider:
int foo(int v);
int foo(int (v));
回答4:
As seen in the following code sample:
int a (int(v)) {
return v;
}
int main() {
std::cout << a(5); //prints 5
}
That line is indeed a declaration. In this example, the parameter is of type int
and named v
. Relating that to your code, the parameter is of type B
and is named v
. That's why you get the similar behaviour when you use double parentheses: because it's the same thing!
来源:https://stackoverflow.com/questions/11138543/c-bizarre-occurrence-of-request-for-member-x-of-y-which-is-of-non-class-type