为什么以下代码会给我一个错误(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;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error: expected constructor, destructor, or type conversion before '*' token
Run Code Online (Sandbox Code Playgroud)
我应该如何定义Foo<A>::foo()函数(使用正确的返回类型)?
ASk*_*ASk 19
这是一个称为" 两阶段查找 "的问题.基本上,由于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;
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*itb 13
通常的typename问题:
template<class A>
typename Foo<A>::AVec* Foo<A>::foo() { // error on this line
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
请记住:作为一般规则,所有依赖于模板参数的限定名称都需要typename在它们之前.