在模板中使用typedef和typename

时间:2011-12-12 09:52:26

标签: c++ templates typedef derived typename

我想在模板化的类中定义一个类型名称,我可以在别处使用它来引用类中成员的类型。

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的声明。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

typename只能用于限定合格的名称;它没有 紧随其后应用名称,但是对于限定名称, 即在:

typedef typename T::X x;

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