template的使用,泛式编程

2023-11-10

一个偶然的机会,让我接触到了泛式编程,它的美妙简直让我沉迷其中,短时间的学习,让我喜欢上了这个方法,它的出现让我想到了之前许多不理解的地方,C++中的STl库非常频繁的使用了它,因此特地去学习了一下

/*-----------------对template的学习(泛型编程)-------------------------------*/
作为一个强制语言,它的数据类型在一开始就固定了,因此要编写一段通用的逻辑,可以把任意类型的变量传去处理。
泛型编程 把通用逻辑设计为模板,摆脱了类型的限制,提升了代码的可重用性 
模板定本身不参与编译,而是编译器根绝模板的用户使用模板时提供的参数生成代码,再进行编译 
在现在总结学习template的时候,因为已经有一些C++基础了,因此就直接回用一些STl举例子,因为它里面运用的template是非常丰富的!
这个例子纯属个人YY,如果有大佬认为不对,方便的话请告诉我,评论即可!
例如常用的排序:sort(const T*,len,cmp);
它里面第三个参数,cmp用的就是泛型 ,因为我们使用这个函数的时候,数据类型是很多的,int,ll,string,struct什么的,因此,为了调和这些数据类型之间的冲突,用到了泛型编程template。

现在声明一下,下面的代码我已经在我的编译器上测试过了,可以使用,但是有些我又添了些其他的,因此直接使用的时候要注意注释掉一些代码,否则可能会引起冲突

现在,我们写一个比较的函数,穿入a,b,a大返回1,b大返回-1,相等返回0;

template<typename T>//简单的泛型比较 
int compare(const T &left,const T &right)
{
	if(left!=right)
            return left>right?1:-1;
        else
	    return 0;
}
int main()
{
	//将函数模板复制给一个指定类型的函数指针,
	//让编译器根据这个指针的类型,对实参进行推断 
	//int (*pf) (const int &,const int &)=compare;//推断T的类型为int 
	
	cout<<compare<string>("b","a")<<endl;//这两种的输出结果是一样的
//之前我用的char*,幸好第二天就被队友发现char*不能直接比较....赶紧改成string...感谢队友@henuzy
	cout<<compare('b','a');//编译器自行脑补出的
}

根本不用定义数据类型!这样的话就只用写一个就行了,碰见其他的数据类型直接带进去就好了,大大提高了代码的重复利用性

是不是很赞??!!

例,对任意数据类型的输出,(举例子而已,直接用cout了....)

class Printer{//输出任意类型的数据 
	public:
		template<typename T>
		void print(const T &t){
			cout<<t<<endl;
		}
	
};
int main()
{
	Printer p;
	p.print<const char*>("abc");
	p.print(1);
}

当类中的函数太多要写到外面时,要注意引用该泛型:

template<typename T>
class Printer{
	public:
		void print(T t);
};
template<typename T>
//void Printer::print(T t)//编译错误,注意,这里要引用泛型T
//[Error] 'template<class T> class Printer' used without template parameters
void Printer<T>::print(T t)//正确
{
	cout<<t<<endl;
}
int main()
{
	Printer<string> p;
	p.print("char*");
}

当模板函数的返回值类型需要用到另一个模板参数表示时,无法利用实参推断获取全部的类型参数,两种解决方法: 

1.返回值类型与参数类型完全无关,那么就需要显示的指定返回值类型,其他的类型交给实参推断 此行为与函数的默认实参相同,我们必须从左向右逐一指定 

给几个例子:

template<typename T1,typename T2,typename T3>
T1 sum(T2 v2,T3 v3){
	return static_cast<T1>(v2+v3);
}

template<typename T1,typename T2,typename T3> 
T3 sum_alternative(T1 v1,T2 v2){//返回T3型的函数, 
	return static_cast<T1>(v1+v2);//用到的是T1的数据 
}

//2.返回值类型可以从参数类型中获得,那么把函数写成 尾置 返回类型的形式,就可以使用实参推断了 

template<typename It>
auto sum(It beg,It end)->decltype(*beg){
	decltype(*beg)ret=*beg;
	for(It it=beg+1;it!=end;it++)
		ret=ret+*it;
	return ret;
}

int main()
{
	//auto:自动推断变量的类型; 
	cout<<1L<<endl;//1L是int 的 1 
	auto long ret=sum<long>(1L,23);//指定T1,T2和T3交由编译器来推断
	
	auto int ret=sum_alternative<long>(1L,23);//error,只能从左向右逐一指定 
	auto int ret=sum_alternative<long,int,long>(1L,23);//seccess,将最后一个T3作为返回类型 
	cout<<ret<<endl;
	/*---------------------------------*/
	vector<int>v={1,2,3,4};
	auto s=sum(v.begin(),v.end());//s=10;
}

当然,有一些实参是会自己转换的,就三个:

实参推断时的自动转换类型
普通对象赋值给const引用:int a=0 - > const T&
数组名转换为头指针:int a[10]={0}; - > T*
函数名转换为函数指针:void func(int a){...} - > T*

函数模板的重载
函数模板之间,函数模板与普通函数之间可以重载。 
普通函数(我们常用的函数)
特殊函数(限定了T的形式,指针,引用,容器等)
普通模板 (对T没有任何限制) 

template<typename T>
void func(T& t){
	cout<<"通用模板函数"<<t<<endl;
}

template<typename T>
void func(T* t){
	cout<<"指针版本"<<*t<<endl; 
}

void func(string *s)//仅仅是一个函数 
{
	cout<<"普通函数"<<*s<<endl; 
}

//模板函数特化,定制函数,指定参数
template<>
void func(int i)
{
	cout<<"int 的定制函数"<<i<<endl; 
}

int main()
{
	int i=10;
	func(i);//调用普通版本,其它函数无法实例化||不匹配 
	func(&i);//调用指针版本,通用版本虽然可以用,但是编译器选择最特殊的版本 
	string s="abc";
	func(&s);//调用普通函数,通用版本和特殊版本虽然可以用,但是编译器选择最特化的版本 
	func<>(&s);//调用指针版本,通过<>告诉编译器我们需要用template而不是普通函数 
	int res=10;
	func(res);//调用特化版本的函数 
}

目前我只会这么多,主要是想用class手动实现一下STL中的一些简单的数据结构;

以后再学再补吧。。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

template的使用,泛式编程 的相关文章

  • 是否有与 posix_memalign 对应的 C++ 版本?

    当我打电话时posix memalign http man7 org linux man pages man3 posix memalign 3 html为类型的对象分配对齐的内存Foo在我的 C 代码中 我需要做一个reinterpret
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • C# 数据表更新多行

    我如何使用数据表进行多次更新 我找到了这个更新 1 行 http support microsoft com kb 307587 my code public void ExportCSV string SQLSyntax string L
  • 使用可变参数包类型扩展的 C++ 函数调用者包装器

    我绑定了一些 API 并且绑定了一些函数签名 如下所示 static bool WrapperFunction JSContext cx unsigned argc JS Value vp 我尝试将对象和函数包装在 SpiderMonkey
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 为什么从字典中获取时会得到 Action<> 的克隆?

    我有以下字典 private Dictionary
  • C++ 中的双精度型数字

    尽管内部表示有 17 位 但 IEE754 64 位 浮点应该正确表示 15 位有效数字 有没有办法强制第 16 位和第 17 位为零 Ref http msdn microsoft com en us library system dou
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐

  • 接口测试&管理续集

    今天应大家需要 接着谈app端数据返回层面的用例设计方法 第二部分给大家安利一个 接口管理平台 以帮助大家解决接口文档维护 接口测试数据Mock 接口自动化测试等问题 希望对小伙伴们有用 言归正传 进入今天的话题 一 用例设计 查漏补缺 数
  • Python网络爬虫之js逆向之远程调用(rpc)免去抠代码补环境简介

    点击上方 Python共享之家 进行关注 回复 资源 即可获赠Python学习资料 今 日 鸡 汤 折戟沉沙铁未销 自将磨洗认前朝 大家好 我是黑脸怪 这篇文章主要给大家介绍jsrpc 方便大家日后在遇到JS逆向的时候派上用场 前言 jsr
  • Unity编辑器拓展(一)实现快速制作书本效果插件

    目录 前言 自定义窗口实现使用的方法 效果演示 前言 Unity自定义书本编辑器窗口 书本功能实现参考教程 Unity代码实现翻书效果 自定义窗口实现使用的方法 EditorWindow GetWindow EditorGUILayout
  • 数据库学习(6)MySQL数据库DDL——索引

    MySQL数据库DDL 索引 创建索引 添加与删除索引 索引的使用原则 数据排序的好处 一旦数据排序之后 查找的速度就会翻倍 现实世界跟程序世界都是如此 创建索引 CREATE TABLE 表名称 INDEX 索引名称 字段 注 排序方法为
  • ToDesk远程控制

    实现远程控制有多简单 https www todesk com download htmlhttps www todesk com download htmlhttps www todesk com download html 电脑浏览器打
  • vue-pdf使用+分页预览+第一查看正常,第二次查看空白解决方案

    重点提示 全网通用pdf查看的功能都是使用vue pdf这个插件 除了各种坑外 最致命的一点就是 它的npm包有一个Bug 在第一次查看之后 再次查看 页面会空白并报错 Error during font loading Failed to
  • jsp、freemarker、velocity、thymeleaf页面方案分析

    1 概述 在java领域 表现层技术主要有三种 1 jsp 2 freemarker 3 velocity 4 thymeleaf 2 jsp 优点 1 功能强大 可以写java代码 2 支持jsp标签 jsp tag 3 支持表达式语言
  • Kattis Doors

    Problem open kattis com problems doors vjudge net contest 183886 problem B Reference 点到线段的最短距离算法 Meaning 有两个球 Alex 和 Bob
  • FastDFS性能调优 know how

    FastDFS性能调优 本篇文章转载于FastDFS作者 余庆 大佬的 FastDFS分享与交流 公众号 众所周知 软件性能调优不是一撮而就的事情 它是一个反复磨合的过程 下面介绍FastDFS 几个性能调优相关的重要参数 供大家参考 1
  • React官网API模块知识点整理(三)

    react版本 16 13 1 1 React 顶层 API React Component React Component 是使用 ES6 classes 方式定义 React 组件的基类 React PureComponent Reac
  • formatter function (value,row,index){ } 参数的含义

    datagarid的formatter属性 formatter function value row index if value 1 return 提交 else if value 99 return 完成 else return 保存
  • 【python爬虫】爬取链家二手房数据

    相信大家买房前都会在网上找找资料 看看行情 问问朋友 今天就带大家扒一扒 链家二手房 的数据 一 查找数据所在位置 打开链家官网 进入二手房页面 选取某个城市 可以看到该城市房源总数以及房源列表数据 二 确定数据存放位置 某些网站的数据是存
  • LocalDate与Date介绍与转换

    一 介绍 java util Date和SimpleDateFormatter都不是线程安全的 而LocalDate和LocalTime和最基本的String一样 是不变类型 不单线程安全 而且不能修改 java util Date月份是从
  • Linux 脚本文件第一行的特殊注释符(井号和感叹号组合)的含义

    我的CSDN主页 My Python 学习个人备忘录 我的HOT博 usr bin env python 的含义 Python 代码存储文件 py 中 经常看到在首行最前端 都是半角符号 输入法英文状态下输入 这是 Linux 系统下指定脚
  • 图像 ISP 处理流程以及新人学习图像的注意点

    1 什么是 ISP ISP 全称 Image Signal Processing 即图像信号处理 景物通过光学图像投射到 sensor 表面后 光电转换为模拟电信号 消除噪声后经过 A D 转换后变为数字图像信号 由于原始的图像是 Baye
  • 2.1 信息的存储

    整数 虽然只能编码一个相对较小的数值范围 但是这种表示是精确的 符点数 虽然可以编码一个较大的数值范围 但是这种表示只是近似的 c c 完全相同的数字表示和运算 java 创建了一套新的数字表示和运算标准 gcc版本 gcc std c11
  • CSS特性---------继承性

    一 继承性 1 1 特性 子元素有默认继承父元素的特点 1 2 可继承的常见属性 font size font weight font family font style text indent text align line height
  • MATLAB医学DICOM影像读取与预处理

    来点有用的 MATLAB医学DICOM影像读取与预处理 一 DICOM文件的读取与解析 二 MR与CT像素处理 三 其他 by HPC ZY DICOM 是医学图像和相关信息的国际标准 常见类型有MR和CT 而它们在处理上有细微的不同 一
  • 【解决 vue-router 报错:Navigation cancelled from “/...“ to “/...“ with a new navigation】

    问题 项目中需要对用户是否登录进行判断 如果用户未登录或者 token 过期就需要跳转登录页面 进行登录验证 所以需要做一个拦截 在跳转登录页面时报了一个错 报错如下图所示 原因 这个错误是 vue router 内部错误 没有进行 cat
  • template的使用,泛式编程

    一个偶然的机会 让我接触到了泛式编程 它的美妙简直让我沉迷其中 短时间的学习 让我喜欢上了这个方法 它的出现让我想到了之前许多不理解的地方 C 中的STl库非常频繁的使用了它 因此特地去学习了一下 对template的学习 泛型编程 作为一