Essential C++ 第三章 范型编程风格

3.1 指针的算术运算

假设我们需要完成以下工作。写一个函数可以同时处理vectorarray内的任意类型元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>
using namespace std;

template <typename elemType>
elemType* find(const elemType *first, const elemType *last, const elemType &value){
if(!first || !last)
return 0;
for(; first != last; ++first)
if(*first == value)
return first;
return 0;
}

int main(){
int ia[8] = {1,1,2,3,5,8,13,21};
double da[6] = {1.5, 2.0, 2.5, 3.0, 3.5, 4.0};
string sa[4] = {"pooh", "piglet", "eeyore", "tigger"};

int *pi = find(ia, ia + 8, ia[3]);
double *pd = find(da, da + 6, da[3]);
string *ps = find(sa, sa + 4, sa[3]);
cout << *pi << " " << *pd << " " << *ps << endl;
return 0;
}

3.2 了解Iterator(范型指针)

1
2
for(iter = svec.begin(); iter != svec.end(); ++iter)
cout << *iter << ' ';

vector<string>::iterator iter = sevc.begin()

此处iter被定义为一个iterator,指向一个vector,后者的元素类型为string。其初值指向 svec 的第一个元素。

3.3 所有容器的共通操作

  • equality(==) 和inequality(!=)
  • assignment(=),将某个容器复制给另一个容器
  • empty()会在容器无任何元素时返回 true,否则返回 false
  • size() 返回容器内目前持有的元素个数
  • clear() 删除所有元素

3.4 使用顺序性容器

顺序性容器用来维护一组排列有序,类型相同的元素。vectorlist是两个最组要的顺序性容器。

vector以一块连续的内存来存放元素,可以进行随机访问,但是插入效率低。

list以双向链接来存储内容,因此可以执行前进或后退操作。list的每个元素都包含三个字段:valueback指针(指向前一个元素),front指针(指向下一个元素),所以list插入,删除效率高,随机访问效率低。

第三种顺序性容器是dequedeque也是以连续内存存储元素。和vector不同的是,deque对于前端元素的插入和删除操作,效率更高;末端亦同。如果我们需要在容器最前端插入元素,并执行末端删除操作,那么deque便很理想。

3.5 使用范型算法

引入头文件

1
#include <algorithm>
  • find() 用于搜索无序集合中是否存在某值。如果找到,则返回一个iterator指向该值,否则返回一个iterator指向 last
  • binary_search() 用于有序集合的搜索。如果找到目标,就返回 true,否则 false
  • count() 返回数值相符的元素数目
  • search() 对比某个容器内是否存在某个子序列。例如{1,3,5,7,2,9},如果搜索子序列{5,7,2},则search()会返回一个iterator指向子序列的起始处,如果子序列不存在,就返回一个iterator指向容器末端。

3.6 如何设计一个范型算法

3.7 使用map

map 被定义为一对(pair)数值。

3.8 使用set

如果想知道某值是否在某个集合中,就可以用set,不统计出现的次数。

3.9 如何使用Iterator Inserter

3.10 使用iostream Iterator