当前位置: 首页 > news >正文

模板中class与typename的辨析

目录

引言:

在声明类时

在定义模板时

模板定义中

依赖类型名称

示例


引言:

在C++编程语言中,typenameclass这两个关键字在许多情况下是可以互换使用的,但它们也有一些特定的用途和含义上的差异。那什么时候该用class,什么时候该用typename呢?

在声明类时

class MyClass {// ...
};typename MyClass2 {// ...
};

尽管技术上允许使用typename来声明类,但在实际编码实践中,几乎总是使用class来声明类,因为这是C++的传统用法,并且更符合语言的习惯。

在定义模板时

在定义模板时,都可以用来声明模板参数作为类型。以下typename与class都可以。

template<typename T>
void function(T param) {// ...
}

typename告诉编译器T是一个类型参数。在C++98标准之前,这是必须的,以区别于非类型模板参数。然而,在C++11及以后的版本中,你可以在模板参数列表中使用class来代替typename。

在有些情况中,只能使用typename,而不能使用class。以下是需要使用typename替换class的情况

模板定义中

当在模板定义内部使用一个依赖于模板参数的类型时,通常需要在该类型前面加上typename关键字,以指示它是一个类型名,而不是静态成员变量或者其它非类型实体。

template <typename T>
class Example {
public:typename T::SubType* ptr; // 这里需要typename,因为SubType依赖于模板参数T
};

(当我们使用静态成员变量时,不需要在前面加上typename关键字,因为静态成员变量不是类型。相反,应该直接使用类名和作用域解析运算符::来访问静态成员变量)

依赖类型名称

在一个模板内部,如果你引用一个依赖于模板参数的类型名称(即嵌套依赖类型),你需要使用typename来明确指出这是一个类型。

template <typename T>
void function() {typename T::NestedType var; // typename用于指示NestedType是T的一个类型
}

示例

例1:

在下述代码中,我们想要完成list<int>类型的打印工作。

	void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){//*it = 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}

        list<int>::const_iterator it = lt.begin();对于这句代码,list<int>已经点名了数据类型是什么,不需要用typename。

例2:

当我们想要同时满足打印其他类型时(list<string>),这时候就无法完成任务,因此我们可以借助模板函数完成。

template<typename t>//template<class t>void print_list(const list<t>& lt){typename list<t>::const_iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;}

 list<t>未实例化的类模板,编译器不能去他里面去找编译器就无法分别list<t>::const_iterator是内嵌类型,还是静态成员变量前面加一个typename就是告诉编译器,这里是一个类型,等list<t>实例化再去类里面去取。

当然,成功实现该功能还得益于,string类型完成了流插入的重载。

例3:

当我们想要再满足可以打印其他容器的内容时(vector(string)),这时候就在需要进行一次修改。

将模板参数t修改为容器参数。

        typename Container::const_iterator it = con.begin();

	template<typename Container>void print_container(const Container& con){typename Container::const_iterator it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;}


 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Chainlit快速实现AI对话应用并将聊天数据的AWS S3 和 Azure Blob云服务中
  • Android Studio本地加速安装gradle
  • DrawState与wms绘制流程梳理
  • RabbitMQ延迟队列
  • H5 优化手段
  • 《新一代数据可视化分析工具应用指南》正式开放下载
  • go语言创建协程
  • 4章7节:用R做数据重塑,行列命名和数据类型转换
  • 【IT行业研究报告】Internet Technology
  • Android网络库:Volley、Retrofit和OkHttp的比较与应用
  • ARM/Linux嵌入式面经(二一):诺瓦科技
  • Spring Boot 的Web开发
  • Linux 下 ETCD 安装、配置与命令使用总结
  • 【Spark集群部署系列二】Spark StandAlone模式介绍和搭建以及使用
  • Docker运行Cassandra集群
  • 【mysql】环境安装、服务启动、密码设置
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • express.js的介绍及使用
  • HashMap ConcurrentHashMap
  • Iterator 和 for...of 循环
  • JavaScript DOM 10 - 滚动
  • JavaScript标准库系列——Math对象和Date对象(二)
  • laravel 用artisan创建自己的模板
  • laravel5.5 视图共享数据
  • nodejs:开发并发布一个nodejs包
  • PHP 7 修改了什么呢 -- 2
  • PHP的Ev教程三(Periodic watcher)
  • Python进阶细节
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • sublime配置文件
  • 今年的LC3大会没了?
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 配置 PM2 实现代码自动发布
  • 前端代码风格自动化系列(二)之Commitlint
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 运行时添加log4j2的appender
  • elasticsearch-head插件安装
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​马来语翻译中文去哪比较好?
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • #vue3 实现前端下载excel文件模板功能
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (k8s中)docker netty OOM问题记录
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (四)进入MySQL 【事务】
  • (一)python发送HTTP 请求的两种方式(get和post )
  • .net core 外观者设计模式 实现,多种支付选择
  • .Net IOC框架入门之一 Unity
  • .Net Memory Profiler的使用举例
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .net生成的类,跨工程调用显示注释