具有typedef返回值的模板化成员函数

Fra*_*ank 10 c++ templates

为什么以下代码会给我一个错误(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

这是一个称为" 两阶段查找 "的问题.基本上,由于Afoo()定义中的模板参数,编译器无法知道何时首次解析模板,无论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)

  • 我相信在两阶段查找链接中我错了.正确的解释是 - 当查找嵌套的依赖名称(依赖于未知模板参数的名称,即Foo <A> :: Bar)时,它被假定为不是类型.唯一的例外是在基类列表中.至于编译器修复返回类型 - 否,模板实例化发生的时间要晚得多; 在编译器对代码执行的第一次扫描期间收到错误 (2认同)

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在它们之前.