为什么下面的代码会给我一个错误(g ++ 4.1.2)?
template<class A>
class Foo {
public:
typedef std::vector<A> AVec;
AVec* foo();
};
template<class A>
Foo<A>::AVec* Foo<A>::foo() { // error on this line
return NULL;
}
错误是:
error: expected constructor, destructor, or type conversion before '*' token
我应该如何定义Foo<A>::foo()
函数(使用正确的返回类型)?
答案 0 :(得分:19)
这是一个名为“two-stage lookup”的问题。基本上,由于A
是foo()
定义中的模板参数,因此编译器无法知道何时首次解析模板,Foo<A>::AVec
是一种类型还是存在(例如,因为可能存在Foo<Bar>
的特殊化,它根本不包含typedef。它只会知道模板实例化中的内容,这会在以后发生 - 而且这个阶段为时已晚。
正确的方法是使用typename
关键字来表明这是一种类型:
template<class A>
class Foo {
public:
typedef std::vector<A> AVec;
AVec* foo();
};
template<class A>
typename Foo<A>::AVec* Foo<A>::foo() {
return NULL;
}
答案 1 :(得分:13)
通常的typename
问题:
template<class A>
typename Foo<A>::AVec* Foo<A>::foo() { // error on this line
return NULL;
}
请记住:作为一般规则,依赖于模板参数的所有限定名称都需要typename
。
答案 2 :(得分:-1)
我真的不知道,但是尝试将typedef放在课堂之外。