c++模板及STL标准模板库

类型模板之模板函数与模板类

模板函数: 数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
示例-一个XXX add()模板函数,在执行时,就会分配出具有其上的两个加法函数功能的函数。

#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;
}
#endif

template<typename XXX>
XXX add(XXX a, XXX b)
{
	return a+b;
}

int main()
{
	cout<< add(1, 2) <<endl;
	cout<< add(1.1, 2.3) <<endl;
}

模板类

template <class T>
class List{
public:
	List();
	~List();
private:
	Tarr[100];
	int num;
};

示例函数

//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

//main.cpp
#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();
}

非类型模板以及特化

非类型模板: 模板参数不限定于类型,普通值也可作为模板参数。在基于类型的模板中,模板实例化时所依赖的是某一类型的模板参数,你定义了一些模板参数(template)未加确定的代码,直到模板被实例化这些参数细节才真正被确定。而非类型模板参数,面对的未加确定的参数细节是指(value),而非类型。当要使用基于值的模板时,你必须显式地指定这些值,模板方可被实例化。

//非类型模板
template<class T,int SIZE>
class List{
public:
	List();
	~List();
private:
	T arrr[SIZE];
	int num;
};

特化模板: 通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,这时就需要对这个函数模板的传入类型进行特化。

//模板特化
template<>
class List{
public:
	List();
	~List();
private:
	int arr[100];
	int num;
};
//模板偏特化
template<class A,class B>
class C{
	A a;
	B b;
};

template<class B>
class C<int, B>{
};

示例

#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;
}
#endif

template<typename XXX>
XXX add(XXX a, XXX b)
{
	return a+b;
}

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.3) <<endl;
	cout<< add(true, false) <<endl;
	cout<< add(true, true) <<endl;
}

链表实现

用c++实现一个链表

#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;
}

迭代器

#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++;
	}

}

STL容器

STL容器包括顺序容器和关联容器。

顺序容器:
vector
list
deque
适配器(statck、queue、priority_queue)
关联容器:
map
set  //tree
multimap
multiet

顺序容器

vector:顺序表
insert();
push_back();
erase();
pop_back();
empty();
begin();
end();
......
list:链表
insert();
push_back();
erase();
pop_back();
empty();
front();
back();
sort();
deque:双端
insert();
push_back();
erase();
pop_back();
empty();
push_front();
stack:
适配器,它可以将任意类型的序列容器转换为一个堆栈,一般使用deque作为支持的序列容器。
元素只能后进先出(LIFO)
push();
top();
pop();注意,出栈操作只是删除栈顶元素,并不返回该元素
queue:
适配器,它可以将任意类型的序列容器转换为一个队列,一般使用deque作为支持的序列容器。
元素只能先进先出(FIFO)
push();
front()/back();
pop();注意,出栈操作只是删除栈顶元素,并不返回该元素

关联容器

map:键值对(key/value)容器
map<string,double> stu;
insert(make_pair<string,double>("john", 95.5));
stu["keiven"] = 80.0;

cout<< "john :" <<stu["john"] <<endl;
cout<< "keiven:" <<stu["keiven"] <<endl;
set:
set<int> a;
a.insert(1);
a.insert(3);
a.insert(5);
if(a.end != a.find(3))
	cout<< "have" <<endl;
if(a.end() != a.find(30)
	cout<< "have 30"<<endl;

示例代码(有STL参考手册,上面有标准模板的使用方法)

#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;  //可以打印出其相关的绑定,本处打印出111331
}

STL算法

sort(b,e)  //排序算法
sort(b,e,回调函数)  //
unique(b,e);  //去掉重复元素,使用该算法前,要先对元素进行排序
find_if(b,e.谓词);  //找对象
count_if(b,e,谓词);  //统计满足某种要求的个数
for_each(b,e,回调函数);  //遍历一个有起止的对象,可以在回调函数中对对象进行处理

示例代码

#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;
*/
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值