2009-05-24 82 views
9

为什么下面的代码给我一个错误(g ++ 4.1.2)?带有typedef返回值的模板成员函数

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()功能?

回答

17

这是一个叫做“two-stage lookup”的问题。基本上,因为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; 
} 
-1

我真的不知道,但可以尝试在类之外放置typedef。

13

通常typename问题:

template<class A> 
typename Foo<A>::AVec* Foo<A>::foo() { // error on this line 
    return NULL; 
} 

记住:作为一般规则,全部合格取决于模板参数的名称在它们之前需要typename