使用g ++ 4.6编译的以下程序产生错误
request for member ‘y’ in ‘a2’, which is of non-class type ‘A<B>(B)’
在最后一行:
#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;
}
从代码中包含的工作变量可以看出,在A的构造函数的参数周围添加括号可以解决问题。
我看到一些由构造函数调用解释为函数声明引起的相关错误,比如创建一个没有参数的构造函数,但是使用大括号:
myclass myobj();
但在我看来
A<B> a2(B(v));
不能解释为函数声明。
有人可以向我解释发生了什么事吗?
答案 0 :(得分:8)
这是最令人烦恼的解析的情况,其中编译器将A<B> a2(B(v))
解释为函数的声明。这样:
A<B>
是返回类型
a2
是函数名称
B
是参数
的类型
v
是参数名称
所以,当你在做什么时
std::cout << a1.y.u << " " << a2.y.u << std::endl;
编译器不认为a2.y.u
是一个类,这就是你得到non-class type
错误的原因。
此外,由于函数声明中不允许使用双括号,因此版本A<B> a2((B(v)));
可以工作,因为编译器不再将其解释为函数声明,而是作为变量声明。
答案 1 :(得分:2)
我认为你已经得到了“最令人烦恼的解析”,这意味着A<B> a2(B(v));
被解析为函数声明而不是变量声明。
答案 2 :(得分:2)
如以下代码示例所示:
int a (int(v)) {
return v;
}
int main() {
std::cout << a(5); //prints 5
}
这条线确实是一个宣言。在此示例中,参数的类型为int
,并命名为v
。将其与您的代码相关联,该参数的类型为B
,并命名为v
。这就是为什么当你使用双括号时你得到类似的行为:因为它是一样的!
答案 3 :(得分:2)
这是一个功能声明:
A<B> a2(B(v));
//is same as:
A<B> a2(B v);
//consider:
int foo(int v);
int foo(int (v));