关键字typename的使用
1.关键字typename被用来作为类型之前的标志符号。例如:
template<class T>
class MyClass
{
typename T::SubType * ptr;
……
};
这里,typename指出SubType是class T中定义的一个类型,因此ptr是一个指向T::SubType类型的指针。如果没有关键字typename,SubType会被当成一个static成员,于是:
T::SubType * ptr;
会被解释为类型T内的数值SubType与ptr的乘积。
SubType成为一个类型的条件是,任何一个用来取代T的类型,其内部都必须提供一个内部类型SubType的定义。例如:将型别Q当作template参数:
MyClass<Q> x;
必要条件类型Q中有如下的内部类型定义:
class Q
{
typename int SubType;
……
};
此时,MyClass<Q>的ptr成员变成了一个指向int类型的指针。子类型也可以为自定义数据类型(例如class):
class Q
{
class SubType;
……
};
注意,如果要把一个template中的某个标志符指定为一种类型,就算意图显而易见,关键字typename也不可或缺。因此C++一般的规则是,除了以typename修饰的之外,template内的任何标志符都被视为一个值,而不是一个类型。
2.在模板中代替class:
在写一个模板函数或者模板类时,常常第一句写为template<class T>,这里的将T定义为任意数据类型,在函数被调用时由调用者指定。这个类型由class引导,但型别本身不一定是class——任何数据类型只要提供template定义式所拥有的操作,都可适用此模板。class的使用原是为了避免增加新的关键字,然而最终还是不得不引入了一个新的关键字typename,此处也可以使用typename。
因此,上述例子可以写为:
template<typename T>
class MyClass
{
……
};
这里主要说明了typename的使用方法。
参考: 《The Standard Library》
1.关键字typename被用来作为类型之前的标志符号。例如:
template<class T>
class MyClass
{
typename T::SubType * ptr;
……
};
这里,typename指出SubType是class T中定义的一个类型,因此ptr是一个指向T::SubType类型的指针。如果没有关键字typename,SubType会被当成一个static成员,于是:
T::SubType * ptr;
会被解释为类型T内的数值SubType与ptr的乘积。
SubType成为一个类型的条件是,任何一个用来取代T的类型,其内部都必须提供一个内部类型SubType的定义。例如:将型别Q当作template参数:
MyClass<Q> x;
必要条件类型Q中有如下的内部类型定义:
class Q
{
typename int SubType;
……
};
此时,MyClass<Q>的ptr成员变成了一个指向int类型的指针。子类型也可以为自定义数据类型(例如class):
class Q
{
class SubType;
……
};
注意,如果要把一个template中的某个标志符指定为一种类型,就算意图显而易见,关键字typename也不可或缺。因此C++一般的规则是,除了以typename修饰的之外,template内的任何标志符都被视为一个值,而不是一个类型。
2.在模板中代替class:
在写一个模板函数或者模板类时,常常第一句写为template<class T>,这里的将T定义为任意数据类型,在函数被调用时由调用者指定。这个类型由class引导,但型别本身不一定是class——任何数据类型只要提供template定义式所拥有的操作,都可适用此模板。class的使用原是为了避免增加新的关键字,然而最终还是不得不引入了一个新的关键字typename,此处也可以使用typename。
因此,上述例子可以写为:
template<typename T>
class MyClass
{
……
};
这里主要说明了typename的使用方法。
参考: 《The Standard Library》