STL —— string(1)

目录

1. 模板

1.1 泛型编程

1.2 函数模板

1.2.1 函数模板概念

1.2.2 函数模板格式

1.2.3 函数模板的原理

1.2.4 显式实例化

1.2.5 模板参数的匹配原则

1.3  类模板

1.3.1 类模板定义格式

 1.3.2 类模板的实例化

2.  STL —— string类

2.1 STL 简介

2.2 标准库中的string类

2.2.1 string类的构造函数 

2.3 string类容量操作

2.4 遍历string类

2.4.1 operator[]

2.4.2 迭代器iterator

2.4.3 范围for


1. 模板

1.1 泛型编程

  • 当我们要实现两个元素交换的时候,由于不知道要交换什么类型的两个值,可能要写多个参数不同的重载函数,例如:
void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}
void Swap(char& left, char& right)
{
	char temp = left;
	left = right;
	right = temp;
}
  • 即使我们使用函数的重载能够实现函数的功能,但是这样写代码会显得比较冗余,那我们能不能写一个模板来让编译器帮我们生成代码呢?  答案是可以的。

1.2 函数模板

1.2.1 函数模板概念

  • 函数模板与函数参数类型无关,编译器不会直接调用模板,而是利用模板实例化出一个函数,然后在调用。

1.2.2 函数模板格式

  • 函数模板通常采用 template<typename T1, typename T2......>的形式,这里的 typename 可以换成 class,例如:
template <typename T>
void Swap(T& x, T& y)
{
	T t = x;
	x = y;
	y = t;
}

int main()
{
	int a1 = 10, a2 = 20;
	Swap(a1, a2);
	return 0;
}

1.2.3 函数模板的原理

  • 函数模板实际上是编译器检测你所传入的参数的类型,然后自动帮你生成一份函数,之后再调用。

1.2.4 显式实例化

  • 那如果我们传入的参数类型不同那该怎么办呢?比如:

template <class T>
T Add(T& left, T& right)
{
	return left + right;
}

int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 1.1, d2 = 2.2;
	Add(a1, d1);
	return 0;
}

这个时候编译器会编译不通过,因为当你传入a1 的 时候,编译器自动会把 T 推演成 int 类型, 但是看到 double 又会把 T 推演成 double 类型,编译器不知道该听谁的,所以会报错,那该如何处理呢? 这里给出三种方法:

  1. 强制类型转换:
    template <class T>
    // 注意这里的第二个参数要加上const
    T Add(T& left, const T& right)
    {
    	return left + right;
    }
    
    int main()
    {
    	int a1 = 10, a2 = 20;
    	double d1 = 1.1, d2 = 2.2;
    	Add(a1, (int)d1);
    	return 0;
    }

    由于在强制类型转换的过程中会产生临时变量,并且临时变量具有常性,不可被修改,而且传的是引用,因此要加上const。

  2. 多加一个模板参数类型
    template <class T1, class T2>
    T2 Add(T1& left, T2& right)
    {
    	return left + right;
    }
    
    int main()
    {
    	int a1 = 10, a2 = 20;
    	double d1 = 1.1, d2 = 2.2;
    	Add(a1, d1);
    	return 0;
    }
  3. 显示实例化
    template <class T>
    // 这边的const也是类似的道理
    T Add(const T& left, const T& right)
    {
    	return left + right;
    }
    
    int main()
    {
    	int a1 = 10, a2 = 20;
    	double d1 = 1.1, d2 = 2.2;
    	Add<double>(a1, d1);
    	return 0;
    }

    显示实例化会强制编译器把 T 推演成某个类型,格式就例如:Add<double>(a1, d1);

1.2.5 模板参数的匹配原则

  • 一个模板和一个与模板同名的函数可以同时存在,并且模板也可以生成与这个函数参数类型相同的函数,但是如果存在同名函数,且参数类型和要传入的参数类型相同,会首先调用这个函数,如果想让编译器自己生成,就可以用显示实例化,例如:

template <class T>
T Add(const T& left, T& right)
{
	return left + right;
}

int Add(int left, int right)
{
	return left + right;
}

int main()
{
	int a1 = 10, a2 = 20;
	Add(a1, a2);
	Add<int>(a1, a2);
	return 0;
}
  • 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板,例如:
// 专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
}

// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
	return left + right;
}
void Test()
{
	Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
	Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
}
  •  模板函数不允许自动类型转换,但普通函数可以进行自动类型转换:
// 因为普通函数可以进行自动类型转换,因此不需要加上const
int Add(int left, int right)
{
	return left + right;
}

int main()
{
	int a1 = 10;
    double d2 = 20;
	Add(a1, d2);
	return 0;
}

1.3  类模板

1.3.1 类模板定义格式

  • template<class T1, class T2, ..., class Tn>

如下是实现简单的栈类型个类模板:

template<class T>
class Stack
{
public:
	Stack(int capacity)
		:_a(new T[capacity])
		,_top(0)
		,_capacity(capacity)
	{}

	void PushBack(const T& val)
	{
		//CheckCapacity()
		_a[_top++] = val;
	}
	~Stack()
	{
		delete[] _a;
		_top = _capacity = 0;
	}

private:
	T* _a;
	int _top;
	int _capacity;
};
  • 如果要声明定义分离的话,要加入模板参数列表
template<class T>
void Stack<T>::PushBack(const T& val)
{
	//CheckCapacity()
	_a[_top++] = val;
}


template<class T>
Stack<T>::Stack(int capacity)
	:_a(new T[capacity])
	, _top(0)
	, _capacity(capacity)
{}

 1.3.2 类模板的实例化

int main()
{
	Stack<int> st1(8);
	Stack<double> st2(4);
	return 0;
}

2.  STL —— string类

2.1 STL 简介

STL(Standard Template Library)是C++标准库中的一个重要组成部分,提供了丰富的通用数据结构和算法模板。STL的设计目标是提供可复用、高效和类型安全的组件,以便开发人员可以方便地处理各种常见的数据结构和算法问题。

STL主要由以下几个组件组成:

  1. 容器(Containers):STL提供了一系列的容器类模板,如 vectorlistdequesetmap等。这些容器类模板封装了常见的数据结构,如数组、链表、双向队列、集合和映射等,开发人员可以根据需要选择合适的容器来存储和组织数据。

  2. 算法(Algorithms):STL提供了一组常用的算法模板,如排序、查找、合并、删除、遍历等。这些算法可以用于不同的容器,并且具有高度的可组合性,开发人员可以将不同的算法组合在一起以实现复杂的操作。

  3. 迭代器(Iterators):迭代器是STL中用于遍历容器元素的对象,它提供了一种通用的访问方式,使得算法可以独立于容器进行操作。STL提供了多种类型的迭代器,包括输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器,每种迭代器都具有不同的特性和功能。

  4. 函数对象(Function Objects):函数对象是可调用对象,可以像函数一样使用。STL中的算法可以接受函数对象作为参数,以实现不同的操作。STL提供了一些标准的函数对象,如谓词(Predicate)、函数适配器(Function Adapters)等,同时也支持自定义的函数对象。

  5. 分配器(Allocators):STL中的容器使用分配器来管理内存的分配和释放。分配器允许开发人员自定义内存管理策略,以满足特定的需求,如内存池分配器、定制的内存分配器等。

STL的设计理念是以泛型编程为核心,通过使用模板和参数化类型,提供通用的、可复用的组件。STL组件之间的协调和配合使得开发人员能够以更高的抽象层次进行编程,从而提高开发效率并降低代码复杂性。

使用STL可以使得C++开发人员能够更加专注于解决问题本身,而不必过多关注底层的数据结构和算法实现。STL已经成为C++编程中的重要工具和标准实践,广泛应用于各个领域的软件开发。

2.2 标准库中的string类

  •  cplusplus 网站给出的 string 底层的介绍:

string - C++ Reference (cplusplus.com)icon-default.png?t=N7T8https://legacy.cplusplus.com/reference/string/string/

2.2.1 string类的构造函数 

  • cplusplus 网站给出的string类构造函数的介绍:

string::string - C++ Reference (cplusplus.com)icon-default.png?t=N7T8https://legacy.cplusplus.com/reference/string/string/string/

  • 对应的构造函数的用法:
  • 注意这里的 "<<" 和 ">>" 重载库中已经给出,所以可以直接用:
int main()
{
	string s0; // (1)
	string s1("hello world"); // (4)
	string s2(s1); // (2)
	string s3(s1, 5); // (3)
	string s4("hello world", 5); // (5)
	string s5(6, '#'); // (6)
	cout << s0 << endl;
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	return 0;
}

2.3 string类容量操作

size返回字符串有效长度。 

2.4 遍历string类

2.4.1 operator[]

  • string类中已经把[]重载了,可以获取pos位置的元素。
  • string类中的容量操作有一个size,可以返回字符串有效字符长度。
  • begin() 和 end() 在迭代器中,begin获取第一个字符的迭代器,end获取最后一个字符下一个位置的迭代器。

int main()
{
	string s0; // (1)
	string s1("hello world"); // (4)
	string s2(s1); // (2)

	for (size_t i = 0; i < s2.size(); ++i)
	{
		cout << s2[i] << " ";
	}
	cout << endl;


	for (size_t i = 0; i < s2.size(); ++i)
	{
		s2[i]++;
	}
	cout << endl;

	for (size_t i = 0; i < s2.size(); ++i)
	{
		cout << s2[i] << " ";
	}
	cout << endl;
	return 0;
}

 

2.4.2 迭代器iterator

  • 迭代器的用法类似于指针,在string中可能使用[]比较方便,但是在 链表,二叉树等链式结构就得用迭代器了。
int main()
{
	string s0; // (1)
	string s1("hello world"); // (4)
	string s2(s1); // (2)
	string::iterator it = s2.begin();
	while (it != s2.end())
	{
		cout << *it << " ";
		++it;
	}
	it = s2.begin();
	while (it != s2.end())
	{
		*it += 5;
		++it;
	}
	cout << endl;
	it = s2.begin();
	while (it != s2.end())
	{
		cout << *it << " ";
		++it;
	}
	return 0;
}

2.4.3 范围for

int main()
{
	string s0; // (1)
	string s1("hello world"); // (4)
	string s2(s1); // (2)
	for (auto e : s2)
	{
		cout << e << " ";
	}
	return 0;
}

 

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

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

相关文章

Gold Effects

HDRP、URP、LWRP和标准支持 完全可定制的金币效果。几乎每个属性都是可调整的,您可以更改这些效果的颜色、渐变、噪波纹理和整体形状。支持HDRP、URP和LWRP,当然也支持标准渲染器。易于拖放设置,带有定制示例的演示场景。使用标准Unity Animator为箱子制作动画,因此您可以轻…

#鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行

3 月 19 日&#xff0c;#鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行。 现场&#xff0c;深圳市南山区人民政府副区长李志娜发布《2024 年南山区支持鸿蒙原生应用发展首批政策措施清单》&#xff0c;从加强鸿蒙原生应用供给能力、推动鸿蒙原生应用产业集聚、完善鸿蒙原生…

windows管理github代码

资料 windows SSH下载github

Windows抓取密码的四种方式其他各类密码抓取

对于Windows&#xff08;不是域环境&#xff09;我们有四种方法去抓取它的密码 在线读取SAM文件离线读取SAM文件在线读取Lsass进程离线读取Lsass进程 在这次的blog&#xff0c;我们还是用的mimkatz 目录 1.在线读取SAM文件 2.离线读取sam文件 3.在线读取lsass进程 4.离线…

如何与手机共享笔记本电脑的互联网?这里提供详细步骤

这篇文章介绍了如何通过将手机变成Wi-Fi热点来与手机共享笔记本电脑的互联网连接。 如何共享笔记本电脑的互联网连接 你可以通过Wi-Fi或有线共享笔记本电脑的数据连接,具体取决于你的设置。 Windows Windows允许你通过ICS共享你的互联网连接。ICS,或称互联网连接共享,是W…

如何使用 PDF 转换器完成 PDF 转 Word

如果您正在寻找能够轻松将 PDF 转换为 Word 的软件&#xff0c;那么奇客PDF转换器是一个不错的选择。下面这篇文章将指导您如何使用奇客PDF转换器将PDF文件转换为Word。 奇客PDF转换器也称为奇客PDF&#xff0c;是将 PDF 文件内容转换为 Word 文本格式的优秀工具。通过使用 PD…

eNSP实验一(静态)

目录 命名更改 子网划分 配置IP DHCP配置 配置静态路由 NET设置 Telnet及端口映射 命名更改 <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]sysname R1 [R1] 1、R6为ISP&#xff0c;接口IP地址均为公有地址(12.0.0.0/24)&#…

运动想象 (MI) 迁移学习系列 (14) : EEGNet-Fine tuning

运动想象迁移学习系列:EEGNet-Fine tuning 0. 引言1. 主要贡献2. 提出的方法2.1 EEGNet框架2.2 微调 3. 实验结果3.1 各模型整体分类结果3.2 算法复杂度比较3.3 不同微调方法比较 4. 总结欢迎来稿 论文地址&#xff1a;https://www.nature.com/articles/s41598-021-99114-1#cit…

CAD建筑版2024 安装教程

CAD建筑版是一种专门用于建筑设计和绘图的CAD软件版本。它提供了专业的建筑设计工具和功能&#xff0c;帮助建筑师、设计师和工程师在建筑领域进行快速、准确和高效的设计工作。 CAD建筑版具备建筑相关的库和元素&#xff0c;用户可以方便地使用预定义的建筑符号和元素进行建筑…

大气污染扩散模型Calpuff技术应用

目前&#xff0c;大气污染仍为我国亟待解决的环境问题。为了弄清大气污染物排放后对周围环境的影响&#xff0c;需要了解污染物的扩散规律。Calpuff模型是一种三维非稳态拉格朗日扩散模型&#xff0c;可有效地处理非稳态&#xff08;如&#xff0c;熏烟、环流、地形和海岸等&am…

谷歌Gemma大模型部署记录

谷歌Gemma大模型部署记录 配置信息 1.系统&#xff1a;Ubuntu20 2.显卡&#xff1a;RTX3060 6G 一、安装Ollama 官网地址&#xff1a;https://ollama.com/download/linux 按照指令安装 curl -fsSL https://ollama.com/install.sh | sh二、运行模型 输入指令&#xff1a;…

关于订单到期关闭的实现方案

前言 在电商、支付等系统中&#xff0c;一般都是先创建订单(支付单)&#xff0c;再给用户一定的时间进行支付&#xff0c;如果没有按时支付的话&#xff0c;就需要把之前的订单(支付单)取消掉。这种类似的场景有很多&#xff0c;还有比如到期自动收货、超时自动退款、下单后自…

Linux-网络层IP协议、链路层以太网协议解析

目录 网络层&#xff1a;IP协议地址管理路由选择 链路层 网络层&#xff1a; 网络层&#xff1a;负责地址管理与路由选择 — IP协议&#xff0c;地址管理&#xff0c;路由选择 IP协议 数据格式&#xff1a; 4位协议版本&#xff1a;4-ipv4协议版本 4位首部长度&#xff1a;以…

【网站项目】293学生用品采购系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Dockerfile自定义镜像

文章目录 1、镜像结构2、Dockerfile语法3、构建Java项目3.1、基于Ubuntu构建Java项目3.2、基于java8构建Java项目 4、小结 ​&#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用…

【网站项目】291校园疫情防控系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Linux系统——Mysql索引补充知识

目录 一、索引介绍 1.索引的优点 2.索引的分类 3.索引的技术名词 3.1回表 3.2覆盖索引 3.3最左匹配 3.4索引下推 4.索引匹配方式 4.1全值匹配 4.2最左前缀匹配 4.3匹配列前缀 4.4匹配一个范围值 4.5精确匹配某一列并范围匹配另一列 4.6只访问索引的查询 一、索引…

(ROOT)KAFKA详解

生产篇 使用 /** Licensed to the Apache Software Foundation (ASF) under one or more* contributor license agreements. See the NOTICE file distributed with* this work for additional information regarding copyright ownership.* The ASF licenses this file to Y…

python机器学习,这些面试题你会吗

安装 要安装完整的栈或单个包&#xff0c;您可以参考 这里 给出的说明。 注意&#xff1a; Anaconda 是高推荐的&#xff0c; 因为它可以无缝地安装和维护数据科学包。 scikit-learn Scikit是一个用于Python的免费开源机器学习库。 它提供了现成的功能来实现诸如线性回归、 …

JavaScript中的类

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 1、类的声明 1.1 基本的类声明语法 要声明一个类,首先编写class关键字,紧跟着的是类的名字。 class Person {constructor(name) {this.name = name;}sayName() {console.log(this…