类型模板之模板函数与模板类
模板函数: 数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
示例-一个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;
*/
}