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

C++ 模板泛型编程

1、函数模板

概述,泛型编程,不局限于特点类型的方式编写代码,使用泛型编程需要指定实际操作的类型

// typename 可以写成class,多个参数用,分割
template<typename T>
T fun(T a,T b)
{
	return a+b;
}

int a = fun(1,3);	// 通过实参推断出来

// 非类型模板参数
template<int a,int b>
int fun2()
{
	return a+b;
}

fun2<1,2>();	// 显示指定模板参数

template<T c,int a,int b>
int fun3(T c)
{
	return (int)c +a+b;
}
fun3<int,11,22>(11);

template<unsigned L1,unsigned L2>
inline // 模板函数可以是内联函数,放在模板之后就行
int fun4(const char (&p)[L1],const char (&p2)[L2])
{
}
fun4("test","test2");// 系统会根据test,和test2自动推断出来L1和L2的长度,会计算结尾\0

模板定义不会导致编译器生产代码,当函数调用时,编译器才会生产特点版本的代码,编译器生产代码是需要找到函数体,所以一般模板函数都写在.h中

2、类模板

浮点型不能作为非类型模板参数,类类型也不行

template<class T>
class myvector
{
public:
	typedef T* myiterator;

	myvector(const myvector& tmp)
	{

	}
	myvector& operator=(const myvector&)
	{

	}

	void fun();
};

template<class T>
void myvector<T>::fun()
{

}


// 非类型类模板参数
template<class T,int T2>
class A
{
public:
	void fun();
};

template<class T,int T2>
void A<T,T2>::fun()
{
}

A<int,22> s1;
 

3、typename使用场合

1、在模板定义中,其后模板参数时类型
template<typename T,int a,int b>
2、使用类的类型成员,需要typename来标识这是一个类型

template<class T>
class myvector
{
public:
	typedef T* myiterator;

	myvector(const myvector& tmp)
	{

	}
	myvector& operator=(const myvector&)
	{

	}
public:
	myiterator begin();
	myiterator end();
	void fun();
};

template<class T>
typename myvector<T>::myiterator myvector<T>::begin()
{

}

函数中

template<typename T>
typename T::size_type fun(const T& t)
{
	if(t.empty())
	{
		return 0;
	}
	return t.size();
}

string s1 = "hello world";
string::size_type size = fun(s1);

4、函数指针做其他函数的参数

typedef int(*FunPtr)(int,int);

int my(int a,int b)
{
	return a+b;
}

void fun(int a,int b,FunPtr my)
{
	my(a,b);
}

fun(1,2,my);

5、函数模板趣味例子

1

typedef int(*FunPtr)(int,int);

int my(int a,int b)
{
	return a+b;
}

template<typename T,typename F>
void fun(T a,T b,F my)
{
	F(a,b);
}

fun(1,2,my);

2

class A
{
	A()
	{
		cout<<"A构造函数执行"<<endl;
	}
	A(const A& tmp)
	{
		cout<<"拷贝构造函数"<<endl;
	}
	int operator()(int x,int y)const
	{
		return x+y;
	}
}
template<typename T,typename F>
void fun(const T& a,const T& b,F my) 
{
	F(a,b);
}
// 会调用A的构造函数
// A的拷贝构造函数,是因为将a对象传递给函数fun时触发

A a;
fun(1,2,a);


6、using 使用

我们希望前面部分固定,后面通过指定

c++ 98实现这种需求的方式
template<typename ts>
struct wt
{
	typedef std::map<std::string,ts> map_s_ts;
};

wt<int>::map_s_ts map1;	//相当于定义了一个map<std::string,int> 类型

// c++ 11 实现
template<typename ts>
using str_map_t = std::map<std::string,ts>;

总结:using是新类型的别名

7、可变参模板

允许模板中含有0个,和多个,args我们称为一个包,多个参数可以为不同类型,

// 1
template<typename... T>
void myfunc(T... args)
{
	cout<<sizeof...(args)<<endl;	// 打印可变参个数
	cout<<sizeof...(T)<<endl;
}

myfunc();	// 表示0个参数
myfunc(10,20,30)// 表示3个参数

// 2
template<typename U,typename... T>
void myfunc1(U& u,T&... args)
{
	cout<<sizeof...(args)<<endl;	// 打印可变参个数
}
myfunc1(10);	// 至少有一个参数

2、包参数展开

void myfunc1()
{
	cout<<"递归终止函数"<<endl;
}

// 一个参数,一个包,最适合参数包展开,通过递归调用,每次将进来的第一个参数给u,其他参数继续调用
template<typename U,typename... T>
void myfunc1(U& u,T&... args)
{
	cout<<u<<endl;
	myfunc1(args...); 
}
myfunc1(10);	// 至少有一个参数```

相关文章:

  • Retrofit原理解析(二)
  • 数据结构与算法 -- 子序列问题
  • python中namedtuple函数用法详解
  • C++设计模式---模板方法模式
  • 数据结构和算法——绪论
  • 最小生成树算法的相关变形题
  • Android中常用的几种容器视图的使用
  • 随手记面试录
  • VMware软件下载安装以及在VMware中安装Centos-stream
  • JCL入门教程
  • 5.6如何寻找最长回文子串
  • tkinter-event事件
  • Windows10环境gradle安装与配置
  • DELMIA弧焊虚拟仿真:带变位机的机器人弧焊焊接程序自动生成方法
  • Redis 非关系型数据库学习(三)---- Redis 基础知识
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • __proto__ 和 prototype的关系
  • 2017年终总结、随想
  • Android优雅地处理按钮重复点击
  • exif信息对照
  • HomeBrew常规使用教程
  • HTTP 简介
  • Java编程基础24——递归练习
  • Java小白进阶笔记(3)-初级面向对象
  • Linux Process Manage
  • NSTimer学习笔记
  • pdf文件如何在线转换为jpg图片
  • rabbitmq延迟消息示例
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • 初识MongoDB分片
  • 分布式任务队列Celery
  • 悄悄地说一个bug
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 关于Android全面屏虚拟导航栏的适配总结
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • (动手学习深度学习)第13章 计算机视觉---微调
  • ****Linux下Mysql的安装和配置
  • .apk文件,IIS不支持下载解决
  • .bat文件调用java类的main方法
  • .net Signalr 使用笔记
  • .NET 中的轻量级线程安全
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NetCore项目nginx发布
  • .NET分布式缓存Memcached从入门到实战
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • @EnableWebMvc介绍和使用详细demo
  • @EventListener注解使用说明
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [04] Android逐帧动画(一)