c++新经典模板与泛型编程:标准库容器中元素类型的萃取

通过容器(数组)类型萃取元素类型

  1. 用GetEleType类模板进行常规实现

#include <iostream>

#include <vector>
#include <list>

// 泛化版本
template<typename T>
struct GetEleType;

// 特化版本
template<typename T>
struct GetEleType<std::vector<T>>
{
	using type = T;
};

// 特化版本
template<typename T>
struct GetEleType<std::list<T>>
{
	using type = T;
};

template<typename T,std::size_t Size> // 这个特化版本增加了一个模板参数
struct GetEleType<T[Size]> // 萃取出数组元素个数
{
	using type = T;
	static const std::size_t size = Size;
};

int main()
{
	std::cout << "vector<double>的元素类型为:" << typeid(GetEleType<std::vector<double> >::type).name() << std::endl;
	std::cout << "list<int>的元素类型为:" << typeid(GetEleType<std::list<int> >::type).name() << std::endl;
	std::cout << "float[45]的元素类型为:" << typeid(GetEleType<float[45]>::type).name() << std::endl;
	std::cout << "float[45]的数组元素数量为:" << GetEleType<float[45]>::size << std::endl;


	return 0;
}

在这里插入图片描述
这个数组、vectorlist的元素类型萃取,还是很有意思的

  1. 引入函数模板PrintEleTyp

#include <iostream>

#include <vector>
#include <list>

// 泛化版本
template<typename T>
struct GetEleType;

// 特化版本
template<typename T>
struct GetEleType<std::vector<T>>
{
	using type = T;
};

// 特化版本
template<typename T>
struct GetEleType<std::list<T>>
{
	using type = T;
};

template<typename T,std::size_t Size> // 这个特化版本增加了一个模板参数
struct GetEleType<T[Size]> // 萃取出数组元素个数
{
	using type = T;
	static const std::size_t size = Size;
};

template<typename T>
void PrintEleType(const T& container)
{
	std::cout << "容器[数组]的元素类型为:" << typeid(GetEleType<T>::type).name() << std::endl;
}

int main()
{

	std::vector<double> my_vec_double;
	PrintEleType(my_vec_double);

	std::list<int> my_list_int;
	PrintEleType(my_list_int);

	float my_array_float[45];
	PrintEleType(my_array_float);

	int a = 5;
	std::cout << typeid(a).name() << std::endl;
	return 0;
}

在这里插入图片描述


获取一个数据的类型,从此拨云开雾,成了一个简单的乐趣

  1. GetEleType类模板的改进
    无论是std::vetor还是std::list,其内部都定义了该容器对应的元素类型,代码大概类似如下:
template<class T>
struct vector
{
	// ...
	using value_type = T;
};

所以,其实是可以直接获取std::vector容器中的元素类型。


std::cout << "vector<double>的元素类型为:"<<
 typeid(std::vector<double>::value_type).name() << std::endl;

也可以改造一下GetEleType类模板,为泛化版本增加定义,取消针对容器的特化版本,改造后如下:


#include <iostream>

#include <vector>
#include <list>

 泛化版本
//template<typename T>
//struct GetEleType;
//
 特化版本
//template<typename T>
//struct GetEleType<std::vector<T>>
//{
//	using type = T;
//};
//
 特化版本
//template<typename T>
//struct GetEleType<std::list<T>>
//{
//	using type = T;
//};
//
//
//template<class T>
//struct vector
//{
//	// ...
//	using value_type = T;
//};

// 泛化版本,用泛化版本实现对容器类型的支持
template<typename T>
struct GetEleType
{
	using type = typename T::value_type; // 针对容器
};
// 针对数组的特化版本内容不变
template<typename T,std::size_t Size>
struct GetEleType<T[Size]>
{
	using type = T;
	static const std::size_t size = Size;
};

// 别名模板:真强大,加一层,直接从(GetElType<T>::type 省为 EleType<T>)
// 这不就是把复杂的事情简单化吗,高手中的高手
template<typename T>
using EleType = typename GetEleType<T>::type;

template<typename T>
void PrintEleType(const T& container)
{
	// std::cout << "容器(数组)的元素类型为:" << typeid(GetEleType<T>::type).name() << std::endl;
	std::cout << "容器[数组]的元素类型为:" << typeid(EleType<T>).name() << std::endl;
}

int main()
{

	std::vector<double> my_vec_double;
	PrintEleType(my_vec_double);

	std::list<int> my_list_int;
	PrintEleType(my_list_int);

	float my_array_float[45];
	PrintEleType(my_array_float);

	int a = 5;
	std::cout << typeid(a).name() << std::endl;
	return 0;
}

在这里插入图片描述


这个代码的运行结果,事实胜于雄辩,解释了标准库容器源码中using value_type = T;的存在。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/234154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【rabbitMQ】模拟work queue,实现单个队列绑定多个消费者

上一篇&#xff1a; springboot整合rabbitMQ模拟简单收发消息 https://blog.csdn.net/m0_67930426/article/details/134904766?spm1001.2014.3001.5502 在这篇文章的基础上进行操作 基本思路&#xff1a; 1.在rabbitMQ控制台创建一个新的队列 2.在publisher服务中定义一个…

基于JAVA+SpringBoot+Vue的前后端分离的医院信息智能化HIS系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着科技的不断发展&a…

2023.12.3 关于 Spring Boot 拦截器 和 过滤器

目录 引言 Spring 拦截器实现 实例理解 Spring 过滤器实现 实例理解 拦截器和过滤器的区别 出身不同 触发时机不同 底层实现不同 支持的项目类型不同 使用场景不同 引言 原生 Spring AOP 实现统一拦截有两个难点难点一&#xff1a;定义拦截规则表达式 难点二&#…

四. 基于环视Camera的BEV感知算法-DETR3D

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Cam…

arm平台编译so文件回顾

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、几个点二、回顾过程 1.上来就执行Makefile2.编译第三方开源库.a文件 2.1 build.sh脚本2.2 Makefile3.最终编译三、其它知识点总结 前言 提示&#xff1a;这…

ES6中的继承,String类型方法的拓展

ES6中的继承&#xff1a; 主要是依赖extends关键字来实现继承&#xff0c;使用了extends实现继承不一定要constructor和super&#xff0c;因为没有的话会默认产生并调用它们。 在实现继承时&#xff0c;如果子类中有constructor函数&#xff0c;必须得在constructor中调用一下s…

我对迁移学习的一点理解——领域适应(系列3)

文章目录 1. 领域适应&#xff08;Domain Adaptation&#xff09;的基本概念2.领域适应&#xff08;Domain Adaptation&#xff09;的目标3.领域适应&#xff08;Domain Adaptation&#xff09;的实现方法4.领域适应&#xff08;Domain Adaptation&#xff09;的可以解决的问题…

javaScript(六):DOM操作

文章目录 1、DOM介绍2、DOM&#xff1a;获取Element对象3、DOM&#xff1a;事件监听3.1、事件介绍3.2、常见事件3.3、设置事件的两种方式3.4、事件案例 1、DOM介绍 概念 Document Object Model &#xff0c;文档对象模型 将标记语言的各个组成部分封装为对应的对象&#xff1a…

leetcode 100.相同的树

涉及到递归&#xff0c;最好多画图理解&#xff0c;希望对你们有帮助 100.相同的树 题目 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 题目链接…

一文掌握Ascend C孪生调试

1 What&#xff0c;什么是孪生调试 Ascend C提供孪生调试方法&#xff0c;即CPU域模拟NPU域的行为&#xff0c;相同的算子代码可以在CPU域调试精度&#xff0c;NPU域调试性能。孪生调试的整体方案如下&#xff1a;开发者通过调用Ascend C类库编写Ascend C算子kernel侧源码&am…

项目记录:SpringBoot+Vue部署在阿里云服务器

目录 一、服务器配置 二、后端代码打包 三、前端项目打包 四、nginx配置 一、服务器配置 部署项目需要一个服务器&#xff0c;我们可以选择阿里云的云服务器ECS&#xff0c;在实例界面可以对服务器进行管理&#xff1a; 然后需要在mobaxterm配置jdk、mysql和nginx。注意配…

排序算法之七:归并排序(递归)

基本思想 基本思想&#xff1a; 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1…

Mendix版的电商京东首页长什么样儿?

前言 世界需要大前端。大前端需要Mendix。 近日经常有企业IT侧的朋友反应&#xff0c;自家需要一个神奇的内容管理平台&#xff0c;来快速打造随需应变的公司官网&#xff0c;亦或企业官微&#xff0c;如果能在小程序里呈现产品营销类的功能更好。首先要肯定的是&#xff0c;…

tuxera2023破解版免费下载 NTFS for Mac读写工具(附序列号)

Tuxera ntfs 2023 破解安装包是一个mac读写ntfs磁盘工具允许您访问&#xff0c;它允许您访问NFTS 驱动器上的文件。 该应用程序提供访问访问Mac 设备中NFTS 格式文件的驱动力&#xff0c;因此您有权基于格式文件进行无困难的访问Windows 数据。 在发生电力灾难或断电时使用防损…

NodeJs脚手架(Koa)的简单使用

文章目录 前言一、与express的区别express-generator 提供的功能如下koa-generator 提供的功能如下两个生成器共同支持的项目骨架描述如下 二、使用步骤安装 Koa 生成器使用koa2创建项目PM2的使用 三、基础目录说明配置文件package.json入口文件 bin/www核心文件 app.jsroutes …

[CTFshow 红包挑战] 刷题记录

文章目录 红包挑战7红包挑战8红包挑战9 红包挑战7 考点&#xff1a;xdebug拓展 源码 <?php highlight_file(__FILE__); error_reporting(2);extract($_GET); ini_set($name,$value);system("ls ".filter($_GET[1])."" );function filter($cmd){$cmd s…

C语言精选——选择题Day42

第一题 1. 下面程序输出的结果是&#xff08;&#xff09; #include <stdio.h> int main () {int x;x printf("I See, Sea in C");printf("x%d" , x); } A&#xff1a;2 B&#xff1a;随机值 C&#xff1a;都不是 D&#xff1a;15 答案及解析 D p…

unittest 数据驱动DDT应用

前言 一般进行接口测试时&#xff0c;每个接口的传参都不止一种情况&#xff0c;一般会考虑正向、逆向等多种组合。所以在测试一个接口时通常会编写多条case&#xff0c;而这些case除了传参不同外&#xff0c;其实并没什么区别。 这个时候就可以利用ddt来管理测试数据&#xff…

什么是高防IP,高防IP该如何选择。

高防IP&#xff0c;指的是高防御能力的IP地址。在互联网的世界里&#xff0c;网络安全问题成为一个重要的话题。作为一个用户&#xff0c;你是否曾遇到过被黑客攻击造成的网站瘫痪、信息泄露等问题&#xff1f;如果你是一个企业&#xff0c;你是否考虑过自己公司的网站和业务的…

【基于ESP32无线蓝牙上传电脑Excel透传数据】

【基于ESP32无线蓝牙上传电脑透传数据】 1. 引言2. 环境搭建2.1 硬件准备:2.2 软件准备:2.3. 配置Excel端口接收功能3. 测试代码4. 连接电脑和 ESP324.1 烧录程序4.2 启动蓝牙服务4.3 测试数据透传5. 总结1. 引言 随着物联网技术的发展,越来越多的设备开始支持无线通信,其…