模板初阶和string容器

news2024/11/26 2:49:36

目录

1.模板

函数模板

函数模板的调用规则:

类模板 

 容器与迭代器

string的简单介绍

iterator(迭代器)

begin()与end()

rbegin()和rend()

 Capacity(容量)

shrink_to_fit()

Element access(获取字符串中的元素)

Modifiers(修改字符串)

String opertations 

其他 


1.模板

什么是模板?模板能有什么用?

比如,你想写一个函数处理一些不同类型的数据,虽然数据的类型不同,但函数中处理数据的方法是一致的。如果不应用模板,那么就需要根据处理的数据类型写相应的仅仅只是参数类型不同的函数。

可以通过模板来实现泛式编程,大大减少程序中冗余的代码。

函数模板

例子:

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

double add(double a, double b)
{
	return a + b;
}

int main()
{
	int a = 1;
	int b = 2;
	double c = 2.1;
	double d = 2.3;
	add(a, b);
	add(c, d);
	return 0;
}

向要实现数据的加减,但加减的数据的类型多种多样需要写处理相应数据类型的函数,代码很容易冗余。

这是后就需要使用模板,

template<class T>
T add(T a, T b)
{
	return a + b;
}

template是关键字,说明下面你写的一段代码是个模板

T是模板参数,如果你调用该函数时传的是int类型的数据,那么编译器会将T推导出来为int,并生成相应的参数为int,返回值为int的函数。

template<class T>
T add(T a, T b)
{
	cout << sizeof(T) << endl;
	return a + b;
}

int main()
{
	int a = 1;
	int b = 2;
	double c = 2.1;
	double d = 2.3;
	add(a, b);
	add(c, d);
	return 0;
}

多模板参数

template<class T1,class T2>
//.......

函数模板的调用规则:

1.如果要处理的数据类型已经有实现的函数,那么就不会使用模板

int add(int a, int b)
{
	cout << "已存在的处理int" << endl;
	return a + b;
}

double add(double a, double b)
{
	cout << "已存在的处理double" << endl;
	return a + b;
}

template<class T>
T add(T a, T b)
{
	cout << "模板函数" << endl;
	return a + b;
}

int main()
{
	int a = 1;
	int b = 2;
	double c = 2.1;
	double d = 2.3;
	add(a, b);
	add(c, d);
	return 0;
}

2. 如果没有现成的函数就使用模板生成一个该类型的模板

	float e = 1.1;
	float f = 1.2;
	add(e, f);

3.如果传的参数无论是与已有函数还是模板参数(表面上(只看数据类型不考虑隐式类型转换))都不匹配,那么就可能报一些错误无法正常运行。

	add(a, c);//传一个int,和一个double

如果调用的是已存在的函数,可能存在调用歧义的问题,以上的代码就有这个问题,因为我们实现了一个处理int的函数,一个处理double的函数。并且传的参数一个是int一个是double,如果将double强转为int那么就调用int函数,如果将int强转为double那么就调用double的函数,但不幸的是编译器无法确定强转的顺序的先后,所以有调用歧义,不能运行。

如果调用的是模板呢?

跟上面的解释差不多,无法确定是将int强转为double还是将int强转为double,所以模板无法推导出模板参数T的类型

解决方法:

就是确定对那个数据进行强制类型转换

	add(a, (int)c);//将double强转为int
	add((double) a, c);//将int强转为double

类模板 

template<class T>
class A
{
private:
	T _a;
};
A<int> a;//用int模板实例化
A<double> b;//用double模板实例化

类模板如何实例化出相应的对象的?

类模板会生成相应的类,在通过类的构造函数初始化对象

 容器与迭代器

什么容器?什么又是迭代器?两者之间有什么关系?

容器(container):简单来说就是跟所学的数据结构一样,就是用来存储数据的。比如,顺序表,链表,堆等等。

迭代器(iterator):就是访问数据的工具

关系:迭代器可以用同一种方法来访问不同容器中的数据。

迭代器就是一个类似于指针的东西。

迭代器的底层也是一个类,但string和vector容器的iterator可能是指针。

迭代器的取值范围是左闭右开

迭代器的使用

	string s = "hello world";
	
	for (string::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it;
	}

这个现在不懂没关系,下面会讲到。

string的简单介绍

链接:可以看更详细的使用说明

string - C++ Reference (cplusplus.com)

string是字符串类型

string的底层是一个类。

string姑且算一种容器吧,在C语言中没有string类型,但又字符数组就跟string差不多。

iterator(迭代器)

begin()与end()

begin返回string的起始迭代器

end返回string的结尾的迭代器

可以把返回值理解成类似于指针的东西。

使用:

int main()
{
	string s = "hello world";
	//第一种遍历一遍字符串
	for (string::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it;
	}
	cout << endl;
	//第二种遍历方式
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;
	//第三种遍历(范围for)
	for (auto e : s)
	{
		cout << e;
	}
	return 0;
}

rbegin()和rend()

与begin()和end()不同的是rbegin()和rend(),返回值的类型不同,为反向迭代器reverse_iterator,

rbegin(),rend()begin(),end()
返回值类型reverse_iterator(反向迭代器)iterator
遍历方式从后往前遍历从前往后遍历

 Capacity(容量)

size():返回字符串的大小

length():跟size()的功能一样

capacity():返回容器的大小

max_size():返回能开辟的最大字符串的大小

resize()

改变字符串的size ,但如果想要改变后的大小大于容器的容量,那么就会先扩容,在改变字符的大小。

reserve()

可以扩容,但扩容只能往大的方向扩,如果你想扩容的大小小于等于原本容器的容量,那么就不会扩容。

 vs下的扩容:

	string s;
	int oldcapacity = s.capacity();
	cout << oldcapacity << endl;
	for (int i = 0; i < 1000; i++)
	{
		s.push_back('a');
		int newcapacity = s.capacity();
		if (newcapacity != oldcapacity)
		{
			oldcapacity = newcapacity;
			cout << newcapacity << endl;
		}
	}

 

由上图的代码和结果可知,容器的初始大小为15,之后差不多就是 1.5倍扩容。

 

clear()

将字符串变为一个空串(“”),但不改变容器的大小

empty()

判断该字符串是否是空串。

shrink_to_fit()

可以缩容,将容器缩小到适合字符串的大小可以减少不必要的空间浪费。

使用:

	string s = "hello world";
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.capacity() << endl;
	cout << s.max_size() << endl;
    //扩容
	s.reserve(100);
	cout << s.capacity() << endl;
	s.resize(20);
	cout << s.size() << endl;
    //清理字符串中的内容
	s.clear();
	cout << s << endl;
    //判空
	cout << s.empty() << endl;
	cout << s.capacity() << endl;
    //缩容
	s.shrink_to_fit();
	cout << s.capacity() << endl;

Element access(获取字符串中的元素)

operator[ ]:可以像数组一样通过[ ]访问字符串中的元素。

	string s("hello world");
	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i];
	}
	cout << endl;

at:获得指定位置的元素。

front:获得第一个元素。

back:获得最后一个元素。

Modifiers(修改字符串)

operator+= 

 在字符串之后追加字符串

	string s;
	s += "hello world";
	string s1 = "aaaa";
	s += s1;
	s += 'b';

append

在字符串之后追加字符串

append没有重载的+=好用 

第六个是模板,传的参数是迭代器。

assign :赋值

push_back

在字符串最后追加字符

	string s;
	s += "hello world";
	s.push_back('a');

insert:向指定位置的字符串中插入数据

erase:删除指定位置的字符

	string s("hello world");
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it;
		s.erase(it);
	}

 

因为string的删除是,将指定位置后的字符都向前移动一位,所以不存在迭代器失效的问题。

replace:替换掉stringzhong指定的一段字符串

swap:交换两个字符串,这里的交换明面上交换的是字符串,实际上也交换了字符串的大小和容器的容量 

pop_back:删除字符串最后的元素。

String opertations 

c_str:返回字符串的首地址 

copy: 将字符串中的数据从pos位置开始拷贝len个字符进s指向的数组中。

 find:在字符串中找s指向的内容,并返回存在相应的位置。如果字符串中没有相应的内容,就返回 string::npos.

 

 string::npos 就是string类中的一个静态变量,因为是size_t 所以初始化为-1,npos的只就是size_t的最大值。

返回npos的意思就是找到字符串末尾也没找到相应的内容。

rfind:相较于find,rfing就是从后往前找。

find_first_of:找到第一个字符既在字符串中出现,又在s指向的内容中。

find_last_of:相较于find_first_of,其从后往前找

find_first_not_of:从字符串中,找第一个在不在s指向的内容中出现的字符,

find_last_not_of:从后往前找

substr:返回字符串中,从pos位置开始len长度的字符串。

compare:比较两或某段字符串的 大小

其他 

operator+:将左右字符串相加并返回一个新字符串(相加的结果)

lhs: left hand side(左操作数)

rhs:right hans side(右操作数)

 relational operators:两个字符串之间的关系运算。

swap(std中):这个std的swap会在交换前会发生字符串的拷贝,浪费性能。

void swap(string& x, string& y)
{
	string tmp = x;//tmp会拷贝构造
	x = y;
	y = x;
}

而string类中定义的swap不需要定义一个临时变量,直接就可以交换,效率更高。

重载的operator>> 和 operator<< 可以使流插入和流提取的对象直接为string类,跟方便使用。

getline可以从键盘中读入的字符插入字符串中 ,这里空格也可以读取,但operator>>不可以读取空格。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决@Autowired 注入service 到 static接口方法的问题

1 对类进行 Component 定义 2 定义service及 static service Component public class OperationalJudgment {private static MemberService memberService;Resourceprivate MemberService service;PostConstructpublic void init() {memberServicethis.service;}3 static方法中…

说明本文档目录是软件开发梳理需求常见问题QA文档,方便客户看,也方便我们的售前人员,需求分析人员,ui设计师,原型绘图人员,思维导图绘图人员查看。

https://doc.youyacao.com/117/2150 说明 本文档目录是软件开发梳理需求常见问题QA文档&#xff0c;方便客户看&#xff0c;也方便我们的售前人员&#xff0c;需求分析人员&#xff0c;ui设计师&#xff0c;原型绘图人员&#xff0c;思维导图绘图人员查看。 提示 本内容客户…

flutter:监听路由的变化

问题 当从路由B页面返回路由A页面后&#xff0c;A页面需要进行数据刷新。因此需要监听路由变化 解决 使用RouteObserver进行录音监听 创建全局变量&#xff0c;不在任何类中 final RouteObserver<PageRoute> routeObserver RouteObserver<PageRoute>();在mai…

ATFX汇市:美国大非农数据来袭,美指与欧元或迎剧烈波动

ATFX汇市&#xff1a;今日20:30&#xff0c;美国劳工部将公布6月非农就业报告&#xff0c;其中新增非农就业人口数据最受关注&#xff0c;前值为27.2万人&#xff0c;预期值19万人&#xff0c;预期降幅高达8.2万人。如果公布值确实如预期一般&#xff0c;美联储降息预期将增强&…

国家力推!国家人工智能产业标准化指南

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;作为推动社会进步和产业升级的关键力量&#xff0c;正以前所未有的速度改变着我们的世界。从自动驾驶到智能制造&#xff0c;从智慧医疗到金融科技&#xff0c;人工智能的触角已经深入到了经济社会的各个角…

【trition-server】运行一个pytorch的ngc镜像

ngc 提供了pytorch容器 号称是做了gpu加速的 我装的系统版本是3.8的python,但是pytorch似乎是用conda安装的3.5的: torch的python库是ls支持gpu加速是真的 英伟达的pytorch的说明书 root@a79bc3874b9d:/opt/pytorch# cat NVREADME.md PyTorch ======= PyTorch is a python …

‘艾’公益——微笑行动「广安站」为艾祝福,让笑起舞

艾多美“微笑行动”广安站拉开帷幕 此次爱心帮助7名唇腭裂患儿 重新绽放微笑 艾多美“微笑行动”广安站拉开帷幕 此次爱心帮助7名唇腭裂患儿 重新绽放微笑 不让笑容留有缺憾 每个孩子都有微笑的权利 艾多美向唇腭裂儿童伸出援手 绽放笑容&#xff0c;拥抱全新的未来 2…

VMware替换关键技术:核心业务系统中,访存密集型应用的性能优化

越来越多用户采用虚拟化、超融合以及云平台环境来承载其核心业务&#xff0c;核心业务的高并发对性能的要求尤为严格&#xff0c;在VMware替换的热潮下&#xff0c;原VMware用户也更为关注新平台在核心业务上的性能表现是否对标&#xff0c;或实现超越。深信服将通过系列解析&a…

python语句前面有一个$是什么意思

“$”是汇编语言中的一个预定义符号&#xff0c;等价于当前正汇编到的段的当前偏移值。例如&#xff1a;指令“jmp $3”中的“$”表示当前这条指令在代码段中的偏移量。 代表当前指令的地址&#xff0c;如&#xff1a; data segment str1 db a,b,c,d leng equ $-str 就是当前地…

氛围共处(Ambient Co-presence)丨RTE 共读计划

在同一个网络空间和情境下&#xff0c;营造一种微妙的、隐约感知的、实时同步的感觉。 加入「RTE 共读计划」&#xff1a; 重要的技术&#xff0c;往往是那些不易察觉却无所不在的技术。欢迎阅读「RTE 共读计划」的文章&#xff0c;我们希望通过本计划&#xff1a; • 挖掘到…

JS+CSS+HTML项目-中国国家图书馆

页面做的不多&#xff0c;CSS效果请看哔哩哔哩

谷歌地图Google JS API 实现

demo实现 实现源码&#x1f447; // 谷歌地图Google JS API 实现 <template><div class"myMap"><gmp-map :center"center" zoom"15" map-id"ab6b6643adfa1a70"><gmp-advanced-markerv-for"(res, index) in…

通信安全员考试精选练习题库,2024年备考必刷题!

16.设计单位必须在设计文件中&#xff08;&#xff09;计列安全生产费。 A.全额 B.部分 C.按建设单位要求 D.按工程建设需要 答案&#xff1a;A 17.日最高气温达到&#xff08;&#xff09;℃以上&#xff0c;应当停止当日室外露天作业。 A.38 B.36 C.35 D.40 答案&…

CUDA编程基础

文章目录 1、GPU介绍2、CUDA程序进行编译3、CUDA线程模型3.1、一维网格一维线程块3.2、二维网格二维线程块3.3、三维网格三维线程块3.3、不同组合形式 4、nvcc编译流程5、CUDA程序基本架构6、错误检测函数6.1、运行时API错误代码6.2、检查核函数 7、CUDA记时7.1、记时代码7.2、…

ret2syscall简单总结

主要是自己的简单的学习总结。 知识点 关于系统调用如何传递参数问题&#xff0c;即系统调用约定&#xff08;syscall&#xff0c;int 80h&#xff0c;svc&#xff09;_int 80h intel汇编用法-CSDN博客 ret2syscall的做题思路&#xff08;以32位程序为例&#xff09; - ZikH…

如何从腾讯云迁移到AWS

随着跨境出海潮不断扩大&#xff0c;企业越来越意识到将工作负载迁移到海外节点的必要性&#xff0c;以获取更多功能、灵活性和性能。然而&#xff0c;顺利迁移业务主机并确保业务稳定访问是一项具有挑战性的任务。在此挑战中&#xff0c;借助AWS迁移工具和迁移流程的强大支持&…

一文了解常见DNS结构

很多企业忽略DNS这个关键的组件&#xff0c;而当DNS出现问题是&#xff0c;就会导致网站无法访问、电子邮件无法发送和接收&#xff0c;从而影响到企业的正常运行。而网络团队成员如果想要处理DNS问题就必须对所在网络的DNS架构有一定的理解。 主DNS服务器&#xff1a; 主DNS服…

微信开放能力 微信小程序获取微信头像、昵称、转发功能、分享到朋友圈、手机号验证组件、客服功能等

一、获取微信头像 当小程序需要让用户完善个人资料时&#xff0c;我们可以通过提供的头像、昵称填写能力快速完善示例 在 wxml 文件中 <view><button class"btn" open-type"chooseAvatar" bindchooseavatar"chooseAvatar"><im…

深度报告 | 百度安全携手极越安全发布《整车安全渗透测试白皮书》

注重点&#xff0c;如何确保车辆全生命周期的安全已成为整个行业亟待解决的问题。对于车企而言&#xff0c;通过渗透测试尽量多地发现安全威胁&#xff0c;是确保车辆信息系统的稳定运行、保障用户安全驾驶至关重要的措施。然而&#xff0c;传统的渗透测试方法已无法满足智能网…

谈大语言模型动态思维流程编排

尽管大语言模型已经呈现出了强大的威力&#xff0c;但是如何让它完美地完成一个大的问题&#xff0c;仍然是一个巨大的挑战。 需要精心地给予大模型许多的提示&#xff08;Prompt&#xff09;。对于一个复杂的应用场景&#xff0c;编写一套完整的&#xff0c;准确无误的提示&am…