我想在模板化的类中定义一个类型名称,我可以在别处使用它来引用类中成员的类型。
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的声明。
答案 0 :(得分:4)
编译器已经知道T
是一种类型(class T
),所以在第一种情况下你不需要typename
限定符。 OTOH,编译器事先并不知道T::ElementType1
是一种类型;这取决于T最终会是什么。
答案 1 :(得分:4)
typename
只能用于限定合格的名称;它没有
紧随其后应用名称,但是对于限定名称,
即在:
typedef typename T::X x;
typename
适用于X
,而不是T
。出于这个原因,它
在合格的名称之前是合法的(在此用途中)。非限定名称
必须在编译器可以知道名称是否为a的上下文中
是不是类型。 (实际上,这只是a中定义的类型的问题
依赖基类,这些可以被限定。)