4

我想在模板类中定义一个类型名称,我可以在其他地方使用它来引用类中成员的类型。

template <class T>
class CA
{
public:
    //typedef typename T::iterator iterator_type;
    typedef typename T ElementType1; // compile error on this line
    //typedef T ElementType2;

    T m_element;
};

并像这样使用它:

template <class T>
class CDerived : public CBase<typename T::ElementType1>
{
 //...
};

并声明如下对象:

typedef CDerived<CA> MyNewClass;

这不可能吗?我有一些代码可以在 VS2010 下正确编译,但不能在使用该行的 Xcode 下编译:

typedef typename T ElementType1;

显然,编译器期望在 typename 之后有一个限定名称,但我看不出模板类型怎么会有一个。

在这种情况下,我不明白 ElementType1 和 ElementType2 之间的区别。

我查看了许多关于堆栈溢出的问题,但大多数问题似乎只涉及我的示例中的 iterator_type 之类的声明。

4

2 回答 2

4

编译器已经知道T是类型 ( ),因此在第一种情况下class T您不需要限定符。typenameOTOH,编译器事先并不知道这T::ElementType1是一种类型;这取决于 T 最终是什么。

于 2011-12-12T09:55:35.360 回答
4

typename只能用于限定限定名称;它不应用紧随其后的名称,而是应用限定名称,即:

typedef typename T::X x;

typename应用于,X而不是T. 出于这个原因,在限定名称之前只有合法(在此使用中)。非限定名称必须位于编译器可以知道名称是否为类型的上下文中。(实际上,这只是依赖基类中定义的类型的问题,并且可以限定这些类型。)

于 2011-12-12T09:59:30.710 回答