2

我有一个具有以下结构的模板类

//CFoo.hpp (header file)
template <typename T>
class CFoo {
        struct SFoo {
            T *ptr;
            /* rest is irrelevant */
        } *foo;

    public:
    /* omitting irrelevant parts */
    SFoo* get();
};

现在,如果我在头文件中实现方法SFoo* get()一切正常。但是,如果我将声明和定义分开,我的代码将停止处理以下编译错误。

//CFoo.cpp (source code, example 1)
/* omitting irrelevant parts */
template <typename T>
SFoo* CFoo<T>::get() { return foo; } //ERROR HERE

错误:<where-is-the-error>: error: ‘SFoo’ does not name a type

//CFoo.cpp (source code, example 2)
/* omitting irrelevant parts */
template <typename T>
CFoo<T>::SFoo* CFoo<T>::get() { return foo; } //ERROR HERE

错误:<where-is-the-error>: error: need ‘typename’ before ‘CFoo<T>::SFoo’ because ‘CFoo<T>’ is a dependent scope

我期待有关如何解决此问题的任何提示。提前致谢。

4

3 回答 3

5

您必须使用typename. 请参阅在哪里以及为什么必须放置“模板”和“类型名称”关键字?

//CFoo.cpp (source code, example 2)
/* omitting irrelevant parts */
template <typename T>
typename CFoo<T>::SFoo* CFoo<T>::get() { return foo; }
^^^^^^^^

在 C++11 中,您可以auto改用,因为SFoo将在函数名之后的范围内

template <typename T>
auto CFoo<T>::get() -> SFoo* { return foo; }
于 2012-12-22T11:51:36.513 回答
1

SFoo在类声明之外,您需要完全符合条件: typename CFoo<T>::SFoo.

于 2012-12-22T11:51:49.493 回答
1

通常,typename只要依赖于模板参数的名称是一种类型,就必须使用它。

template <typename T>
typename CFoo<T>::SFoo* CFoo<T>::get() { return foo; }

§ 14.6.2 名称解析

在模板声明或定义中使用并且依赖于模板参数的名称被假定为不命名类型,除非适用的名称查找找到类型名称或该名称由关键字 typename 限定。

于 2012-12-22T11:53:54.993 回答