检查一下:
template <class T>
class Test: public T
{
public:
void TestFunc()
{
T::SubClass bob;
}
};
在为iPhone编译时失败(预期';'在'bob'之前)。适用于其他平台
这是我们实际尝试做的简化示例,它继承自std :: map&lt;&gt;在该类中,创建一个迭代器。
答案 0 :(得分:3)
经常遇到问题。放typename
:
template <class T>
class Test: public T
{
public:
void TestFunc()
{
typename T::SubClass bob;
}
};
T::SubClass
是依赖名称。在解析模板时,编译器还不知道它是否是一个类型。为了仍然能够解析它(并收集由此获得的信息),它假定它不是一种类型。但是,该行必须是一个表达式,并且错过了两个名称之间的运算符。 typename
将告诉它名称是一个类型,然后该行成为一个声明。
可能不明白为什么它失败了,因为整行不能表达。但还有其他情况,这是不可能决定整个声明的形式:
T::SubClass * bob;
这是乘法还是指针声明?编译器将假设它是乘法。如果稍后在实例化模板时它会发现T::SubClass
命名一个类型,它将会出现错误消息。 typename
也会告诉编译器将其解析为声明而不是表达式(通过将T::SubClass
作为类型)。
请注意,有些编译器仍可以在没有typename
的情况下工作(如果我没记错的话,MSVC编译器就是其中之一)。我认为这应该伴随着那些编译器不会进行两阶段名称查找的限制:它们将在实例化时解析完整的模板,并且所有名称,甚至那些在模板定义中不可见的名称,都将是发现(与标准所说的相反,它在定义/实例化时对名称查找的处理方式不同)。
访问模板常见问题解答以获取进一步的帮助:C++ Templates FAQ