C++模板中为何要使用typename或class关键字,二者有何区别?
C++模板参数关键字相关问题解答
为什么仅写template无法正常生效
C++的模板语法强制要求,声明模板时必须明确标注模板的参数列表,说明该模板接收多少个参数、每个参数是类型参数还是非类型参数。如果只写template,编译器无法判断模板的参数规则,无法完成后续的模板解析和实例化操作,必然会抛出语法错误。
你示例中的template<class T>里,class T就是完整的模板类型参数声明:表示当前模板有1个类型参数,后续代码中可以用T来代指调用模板时传入的具体类型,这部分是模板声明不可缺少的组成部分。
typename关键字的作用
typename最核心的作用是告知编译器:其后跟随的标识符是一个类型,而非类的静态成员变量/成员函数。
这个作用在处理模板内的「依赖类型」(即依赖于模板参数的类型)时是必须的,示例如下:
template<class T> void test() { // 不加typename的话,编译器会默认将T::inner_type识别为T的静态成员 typename T::inner_type* ptr; }
如果缺少typename修饰,上面的代码会被编译器解析为「静态成员T::inner_type和指针变量ptr相乘」的表达式,直接触发语法报错。
class和typename的适用场景
- 绝大多数场景下,声明普通模板类型参数时二者完全等价,
template<class T>和template<typename T>的效果没有任何差异。早期C++标准只允许用class声明模板类型参数,后续加入typename后为了兼容旧代码,一直保留了class的这种用法。 - 仅能使用
typename的场景:标记模板内部的依赖类型为类型名,也就是上面示例的typename T::inner_type这类场景,此处不能替换为class。 - 仅能使用
class的场景:声明模板模板参数(即参数本身是一个模板)时,只能用class修饰,示例如下:// 此处模板模板参数Container只能用class修饰,不能替换为typename template<template<typename> class Container, typename T> class Wrapper { private: Container<T> storage; };
内容的提问来源于stack exchange,提问作者Divyanshu Agarwal
相关产品推荐
相关产品推荐

