C++——模板与STL标准模板库

news2025/1/11 8:06:35

目录

一、模板

1.1类型模板

1.2非类型模板

二、STL

2.1链表实现

2.2迭代器

2.3STL容器

2.4STL算法

三、模板特化的匹配规则

(1) 类模板的匹配规则

(2) 函数模板的匹配规则


一、模板

1.1类型模板

#include <stdio.h>
#include <iostream>

using namespace std;
#if 1
int add(int a, int b)
{
    return a+b;
}
double add(double a, double b)
{
    return a+b;
}
#else
template<typename XXX>
XXX add(XXX a, XXX b)
{
    return a+b;
}
#endif
int main()
{
    cout << add(1,2) << endl;
    cout << add(1.1,2.2) << endl;
}

arr.c >> arr.h   :将前面的文件追加到后面的文件的尾巴上

 

#ifndef _ARR_
#define _ARR_

#include <iostream>

using namespace std;

template <typename XXX>
class ARR{
public:
	ARR():tail(0){
	}

	void addtail(XXX data);
	void show(void);
	
private:
	XXX data[100];
	int tail;
};

template <typename XXX>
void ARR<XXX>::addtail(XXX data)
{
	this->data[tail++] = data;
}

template <typename XXX>
void ARR<XXX>::show(void)
{
	int i = 0;
	for(;i<tail; i++)
		cout<< data[i] <<',';
	cout<<endl;
}

#endif

 template <typename XXX>每次使用都要写一次

#include "arr.h"

int main()
{
	ARR<int> arr;

	arr.addtail(1);
	arr.addtail(2);
	arr.addtail(3);
	arr.addtail(4);

	arr.show();

	ARR<double> arr1;

	arr1.addtail(1.1);
	arr1.addtail(22.3);
	arr1.addtail(3.5);
	arr1.addtail(4.9);

	arr1.show();
}

1.2非类型模板

 

#define _ARR_

#include <iostream>

using namespace std;

template <typename XXX, int SIZE>
class ARR{
public:
	ARR():tail(0){
	}

	void addtail(XXX data);
	void show(void);
	
private:
	XXX data[SIZE];
	int tail;
};

template <typename XXX, int SIZE>
void ARR<XXX, SIZE>::addtail(XXX data)
{
	this->data[tail++] = data;
}

template <typename XXX, int SIZE>
void ARR<XXX, SIZE>::show(void)
{
	int i = 0;
	for(;i<tail; i++)
		cout<< data[i] <<',';
	cout<<endl;
}

#endif
#include "arr.h"

int main()
{
	ARR<int, 100> arr;

	arr.addtail(1);
	arr.addtail(2);
	arr.addtail(3);
	arr.addtail(4);

	arr.show();

	ARR<double, 1000> arr1;

	arr1.addtail(1.1);
	arr1.addtail(22.3);
	arr1.addtail(3.5);
	arr1.addtail(4.9);

	arr1.show();
}

#include <stdio.h>
#include <iostream>

using namespace std;
#if 0
int add(int a, int b)
{
    return a+b;
}
double add(double a, double b)
{
    return a+b;
}
#else
template<typename XXX>
XXX add(XXX a, XXX b)
{
    return a+b;
}
#endif
template<>
bool add(bool a, bool b)
{
    if (a == true && b == true)
        return true;
    return false;
}
int main()
{
    cout << add(1,2) << endl;
    cout << add(1.1,2.2) << endl;
    cout << add(true, false) <<endl;
    cout << add(true, true) <<endl;
}

二、STL

2.1链表实现

#include <iostream>
#include <ostream>

using namespace std;

class myList{	
	struct Node{
		Node(int x, Node *ptr=NULL):data(x), next(ptr) { }
		int data;
		Node *next;
	};
public:
	myList():head(NULL) { }
	~myList() {
		while(head)
		{
			Node *tem = head;
			head = head->next;
			delete tem;
		}
	}

	void insert_head(int data)
	{
		Node *node = new Node(data);
		node->next = head;
		head = node;
	}


	friend ostream &operator<<(ostream &out, const myList &list);
private:
	Node *head;
};

ostream &operator<<(ostream &out, const myList &list)
{
	myList::Node *tem = list.head;
	while(tem)
	{
		out<< tem->data <<',';
		tem = tem->next;
	}
	out << endl;

	return out;
}

int main()
{
	myList list;

	list.insert_head(1);
	list.insert_head(2);
	list.insert_head(4);
	list.insert_head(3);

	cout << list;

}

2.2迭代器

 C++迭代器(STL迭代器)iterator详解

百度百科-验证

#include <iostream>
#include <ostream>

using namespace std;

class myList{	
	struct Node{
		Node(int x, Node *ptr=NULL):data(x), next(ptr) { }
		int data;
		Node *next;
	};
public:
	class iterator{
	public:
		iterator(Node *ptr=NULL):pos(ptr) {  }
		iterator &operator++(int)
		{
			if(NULL != pos)
				pos = pos->next;
			return *this;
		}

		int &operator*()
		{
			return pos->data;
		}

		bool operator!=(iterator x)
		{
			return pos != x.pos;
		}
	private:
		Node *pos;
	};
public:
	myList():head(NULL) { }
	~myList() {
		while(head)
		{
			Node *tem = head;
			head = head->next;
			delete tem;
		}
	}

	void insert_head(int data)
	{
		Node *node = new Node(data);
		node->next = head;
		head = node;
	}

	iterator begin()
	{
		return iterator(head);
	}
	iterator end()
	{
		return iterator(NULL);
	}


	friend ostream &operator<<(ostream &out, const myList &list);
private:
	Node *head;
};

ostream &operator<<(ostream &out, const myList &list)
{
	myList::Node *tem = list.head;
	while(tem)
	{
		out<< tem->data <<',';
		tem = tem->next;
	}
	out << endl;

	return out;
}

int main()
{
	myList list;

	list.insert_head(1);
	list.insert_head(2);
	list.insert_head(4);
	list.insert_head(3);

	cout << list;

	myList::iterator i = list.begin();
	while(i != list.end() )
	{
		cout << *i <<endl;
		i++;
	}

}

2.3STL容器

我们把前面迭代器链表模板化一下:

#include <iostream>
#include <ostream>

using namespace std;

template <typename T>
class myList{	
	struct Node{
		Node(T x, Node *ptr=NULL):data(x), next(ptr) { }
		T data;
		Node *next;
	};
public:
	class iterator{
	public:
		iterator(Node *ptr=NULL):pos(ptr) {  }
		iterator &operator++(int)
		{
			if(NULL != pos)
				pos = pos->next;
			return *this;
		}

		int &operator*()
		{
			return pos->data;
		}

		bool operator!=(iterator x)
		{
			return pos != x.pos;
		}
	private:
		Node *pos;
	};
public:
	myList():head(NULL) { }
	~myList() {
		while(head)
		{
			Node *tem = head;
			head = head->next;
			delete tem;
		}
	}

	void insert_head(T data)
	{
		Node *node = new Node(data);
		node->next = head;
		head = node;
	}

	iterator begin()
	{
		return iterator(head);
	}
	iterator end()
	{
		return iterator(NULL);
	}


	template <typename X>
	friend ostream &operator<<(ostream &out, const myList<X> &list);
private:
	Node *head;
};

template <typename X>
ostream &operator<<(ostream &out, const myList<X> &list)
{
	typename myList<X>::Node *tem = list.head;
	while(tem)
	{
		out<< tem->data <<',';
		tem = tem->next;
	}
	out << endl;

	return out;
}

int main()
{
	myList<int> list;

	list.insert_head(1);
	list.insert_head(2);
	list.insert_head(4);
	list.insert_head(3);

	cout << list;

	myList<int>::iterator i = list.begin();
	while(i != list.end() )
	{
		cout << *i <<endl;
		i++;
	}

}

 

 

 

 

 

 举个例子vector

#include <stdio.h>
#include <iostream>
#include <vector>

using namespace std;

int main()
{
#if 1
    vector<int> arr;

    arr.push_back(1);
    arr.push_back(2);
    arr.push_back(3);
    arr.push_back(4);
    arr.push_back(5);
    arr.push_back(6);
#endif

    vector<int>::iterator i = arr.begin();
    while(i != arr.end() )
    {
        cout << *i << endl;
        i++;
    }
}

 如果是个double类型

#include <stdio.h>
#include <iostream>
#include <vector>

using namespace std;

int main()
{
#if 0
    vector<int> arr;

    arr.push_back(1);
    arr.push_back(2);
    arr.push_back(3);
    arr.push_back(4);
    arr.push_back(5);
    arr.push_back(6);
#else
    vector<double> arr;
    arr.push_back(1.2);
    arr.push_back(1.2);
    arr.push_back(1.2);
    arr.push_back(1.2);
    arr.push_back(1.2);
    arr.push_back(1.2);
#endif

//    vector<int>::iterator i = arr.begin();
    vector<double>::iterator i = arr.begin();
    while(i != arr.end() )
    {
        cout << *i << endl;
        i++;
    }
}

 把vector和list结合

#include <iostream>
#include <vector>
#include <list>

using namespace std;

int main()
{
#if 0
	vector<int> arr;

	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);
#endif
//	vector<double> arr;
	list<double> arr;
	arr.push_back(1.2);
	arr.push_back(1.2);
	arr.push_back(1.2);
	arr.push_back(1.2);
	arr.push_back(1.2);

//	vector<int>::iterator i = arr.begin();
//	vector<double>::iterator i = arr.begin();
	list<double>::iterator i = arr.begin();
	while(i != arr.end() )
	{
		cout<< *i <<endl;
		i++;
	}
}

map:

#include <iostream>
#include <map>

using namespace std;

int main()
{
	map<string, string> user_passwd;
	
	user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa", "1111") );
	user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa4", "114411") );
	user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa2", "111331") );
	user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa3", "111441") );

	map<string, string>::iterator i = user_passwd.begin();
	while(i != user_passwd.end())
	{
		cout<< (*i).first<< ',' <<(*i).second <<endl;
		i++;
	}

	cout<< user_passwd["aaa2"] << endl;
}

2.4STL算法

#include <iostream>
#include<algorithm>

using namespace std;

bool cmp(int a, int b)
{
	return a>b;
}

void show(int data)
{
	cout<< data<< endl;
}

bool fcmp(int data)
{
	return data == 34;
}

int main()
{
	//vector<int> arr;
	
	int arr[] = {1,1234,23,4,23,42,34,23,42,34,2,2,2,444,22};
	int n = sizeof(arr)/sizeof(int);

	int *p = find_if(arr, arr+n, fcmp);
	if(p != arr+n)
		cout<<"got it !\n";

	cout <<"num of 34: "<< count_if(arr, arr+n, fcmp) << endl;

/*
	for(int i = 0; i<n; i++)
		cout <<arr[i]<<',';
	cout<<endl;
*/
	for_each(arr, arr+n, show);

	sort(arr, arr+n);
//	sort(arr, arr+n, cmp);
	cout<<"xxxxxxxxxxxxxxxxxxx\n";
	unique(arr, arr+n);

	for_each(arr, arr+n, show);
/*
	for(int i = 0; i<n; i++)
		cout <<arr[i]<<',';
	cout<<endl;
*/
}

三、模板特化的匹配规则

(1) 类模板的匹配规则


最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权
例子:
template <class T> class vector{//…//}; // (a)  普通型
template <class T> class vector<T*>{//…//};  // (b) 对指针类型特化
template <>   class vector <void*>{//…//};  // (c) 对void*进行特化
每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void*才能作为(c)的参数


(2) 函数模板的匹配规则


非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权
例子:
template <class T> void f(T);  // (d)
template <class T> void f(int, T, double); // (e)
template <class T> void f(T*);  // (f)
template <> void f<int> (int) ; // (g)
void f(double);  // (h)
bool b;
int i;
double d;
f(b); // 以 T = bool 调用 (d)
f(i,42,d) // 以 T = int 调用(e)
f(&i) ; // 以 T = int* 调用(f)
f(d);  //  调用(g)

 

参考文献
[1] Bjarne Stroustrup, The C++ Programming Language (Special Edition), Addison Wesley,2000
[2] Nicolai M.Josuttis, The C++ Standard Library – A Tutorial and Reference ,Addison Wesley,1999
[3] Stanley Lippman and Josée Lajoie ,C++ Primier, 3rd Edition ,Addison Wesley Longman ,1998

---------------------------------------------------------------------------------------------------------------------------------

最近有点沉迷看书有几句话感觉很有道理记录一下:

        想要保持人格独立,就必须经济独立,哪怕只是独立一部分,也能过的很从容,下班以后可以干干兼职,可以做做小生意,可以考考证,我觉得这都是非常积极的状态,不要嫌少,积少成多,机会是留给有准备的人的~~

        “人是很复杂的东西,不管遇见谁,都是一场修炼,只有保持自我,才能享受人生!”

        感情就是合适的时间遇上了合适的人,这其中,关键还是合适的时间,这个真没什么遗憾的,因为人生很长,合适的人会有很多,总有一个人在合适的节点等着跟你相遇~~”

        制度这种东西,尤其是专业性很强的制度,搞的人字斟句酌费时费力,懂的人视若珍宝,不懂的人,就当是一堆废纸,感觉通篇都是毫无意义的空话套话。这就是人和人的差别,有些人总能保持热忱,不管周围的人怎么叽叽喳喳,一直知道自己想要的是什么,秉承艺不压身的理念,既来之则安之,既安之则多学点东西,就算学不到什么,长长见识也是好的。有些人总是在抱怨,很少真正静下来心来权衡利弊,很多时候其实就是在随大流,别人抱怨我也抱怨,别人有可能只是嘴花花,只有你自己当了真,各种自以为是,各种抨击别人傻乎乎,看着身边人一个个高升,最终也没意识到,其实小丑只是自己。  

---------------------------------------------------------------------------------------------------------------------------------

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

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

相关文章

深度学习 GAN生成对抗网络-手写数字生成及改良

如果你有一定神经网络的知识基础&#xff0c;想学习GAN生成对抗网络&#xff0c;可以按顺序参考系列文章&#xff1a; 深度学习 自动编码器与生成模型 深度学习 GAN生成对抗网络-1010格式数据生成简单案例 深度学习 GAN生成对抗网络-手写数字生成 一、前言 在前面一篇文章&am…

877. 石子游戏

877. 石子游戏题目算法设计&#xff1a;奇偶算法设计&#xff1a;动态规划题目 算法设计&#xff1a;奇偶 最简单的情况&#xff0c;只有2堆石子&#xff08;石子奇数&#xff09;&#xff0c;先稳赢。 但是四堆情况不同了&#xff0c;如 [3 7 2 3]。 不能直接选最大的&…

2023年五大趋势预测 | 大数据分析、人工智能和云产业展望

随着我们迈入2023年&#xff0c;大数据分析、人工智能和云产业将迎来蓬勃的创新和发展阶段 以下是我们预测的&#xff0c;将对行业格局产生重大影响的五大趋势&#xff1a; 世界在剧变&#xff0c;我们需要尽快寻找行业中的方向&#xff0c;迅速重回轨道 2023年&#xff0c;全…

TryHackMe-NahamStore(常见web漏洞 大杂烩)

NahamStore 漏洞赏金web安全 NahamStore的创建是为了测试您在NahamSec的“漏洞赏金狩猎和Web应用程序黑客入门”Udemy课程中学到的知识。 部署计算机&#xff0c;获得 IP 地址后&#xff0c;进入下一步&#xff01; 写在前面 可能我的顺序&#xff0c;跟别人以及题目都不太一…

spring boot集成activemq(windows)

目录 1.环境配置 2.说明 3.服务启动 4.示例 导入依赖 配置文件 service层 配置类 监听器 5.总结 1.环境配置 下载地址&#xff1a;https://activemq.apache.org/components/classic/download/安装&#xff1a;解压缩即可注意每个版本对应的java版本不一样&#xff0c…

分享96个PHP源码,总有一款适合您

PHP源码 分享96个PHP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 96个PHP源码下载链接&#xff1a;https://pan.baidu.com/s/1B-tNZlbfjT_D3n_Y6ZwfDw?pwduq19 提取码&#xff…

共享自助自习室棋p室茶室办公室电竞篮球馆小程序开发

共享自助自习室棋p室茶室办公室电竞篮球馆小程序开发 多场景应用的共享空间预约系统如:棋牌室;共享办公室&#xff0c;电竞篮球馆&#xff0c;自助民宿等。目前该应用已对接门锁和电控。 前端功能// 多场景应用、预约时间自定义、附近门店一目了然、支持门禁支持电控、首页门…

Windows系统安装轻量级高性能Web服务开发框架OAT++

一、软件简介 oat 是一个轻量级高性能 Web 服务开发框架&#xff0c;采用纯 C 编写而成。官网&#xff1a;https://oatpp.io/ 这个坑爹的网址在国内经常打不开&#xff0c;要多刷新几次。Github: https://github.com/oatpp/oatpp 当前版本&#xff1a; 1.3.0 其主要特性…

用PYTHON自动登录SAP GUI

我们都知道&#xff0c;SAP原生的“脚本录制和回放”功能是在用户进入到某一个SAP”用户指定系统“后才可以启用&#xff1a; 也就是说&#xff0c;从这里开始&#xff0c;您可以通过脚本录制&#xff0c;生成用户名、密码的输入和SAP登录过程的完整代码&#xff1b; 那么我们…

第三层:C++对象模型和this指针

文章目录前情回顾C对象模型和this指针类成员变量和类成员函数的储存this指针this指针概念this指针用途用途1解释用途2解释空指针调用成员函数const修饰的成员变量常函数内可以被修改的值突破&#xff01;步入第四层本章知识点&#xff08;图片形式&#xff09;&#x1f389;wel…

Matlab中算法结合Simulink求解直流微电网中功率

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

初识 jQuery(JavaScript 框架)

初识 jQuery&#xff08;JavaScript 框架&#xff09;参考描述jQuery使用 jQuery 的开发优势&#xff08;部分&#xff09;获取jQuery 语法基础语法入口函数$()jQuery 与 $参数DOM 与 jQuery模板获取DOM 对象jQuery 对象转换DOM 对象转换为 jQuery 对象$()jQuery 对象转换为 DO…

Linux系统管理中Nginx和python的安装以及python虚拟环境软件的安装与使用(四)

1、Nginx的安装和配置&#xff1a; 说明&#xff1a;Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器&#xff1b;同时也是一个IMAP、POP3、SMTP代理服务器&#xff1b;Nginx可以作为一个HTTP服务器进行网站的发布处理&#xff0c;另外Nginx可以作为反向代理进…

C++:list结构算法

List 1.元素在逻辑上具有线性次序&#xff0c;物理地址不做限制。 2.哨兵节点&#xff0c;header和trailer&#xff0c;封装后外部不可见。 3.重载操作符[]&#xff0c;实现下标和位置转换。 4.有序查找无序查找 5.前插入算法&#xff0c;首先创建新节点 然后使new成为this节点…

设计模式之代理模式(静态动态)代理

前言&#xff1a;二十三种设计模式中的一种&#xff0c;属于结构型模式。它的作用就是通过提供一个代理类&#xff0c;让我们在调用目标方法的时候&#xff0c;不再是直接对目标方法进行调用&#xff0c;而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥…

PHP设计模式

目录 一、使用设计模式目的 二、设计模式的七大原则 三、创建型模式&#xff08;构建型模式&#xff09; 1、单例模式 代码实例 2、工厂模式 2.1、工厂模式——简单工厂模式 简单工厂模式的代码实例 2.2、工厂模式——工厂方法模式 工厂方法模式的代码实例 2.3、工厂…

java开发环境配置及问题排查

Java程序必须运行在JVM之上&#xff0c;所以&#xff0c;我们第一件事情就是安装JDK。 JDK(Java Development Kit)&#xff0c;是Java开发工具包&#xff0c;它提供了Java的开发环境(提供了编译器javac等工具&#xff0c;用于将java文件编译为class文件)和运行环境(提 供了JVM…

Java内存模型和线程安全

Java内存模型和线程安全Java内存模型引言volatile关键字synchronized关键字Java线程Java线程安全synchronized锁优化锁优化技巧列举自旋锁锁消除锁粗化具体实现轻量级锁偏向锁Java内存模型 引言 对于多核处理器而言,每个核都会有自己单独的高速缓存,又因为这多个处理器共享同一…

JavaWeb-会话技术

JavaWeb-会话技术 1&#xff0c;会话跟踪技术的概述 对于会话跟踪这四个词&#xff0c;我们需要拆开来进行解释&#xff0c;首先要理解什么是会话&#xff0c;然后再去理解什么是会话跟踪: 会话:用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff…

反射机制.

文章目录概述两个疑问关于java.lang.Class的理解获取Class实例的方式哪些类型可以有Class对象了解类的加载器掌握加载配置文件的另一种方式创建运行时类的对象体会动态性获取运行时类的完整结构调用运行时类的制定结构每日一考动态代理概述 1、反射是动态语言的关键 2、动态语…