附录G 标准模板库方法和函数

标准模板库(STL)旨在提供通用算法的高效实现,它通过通用函数(可用于满足特定算法要求的任何容器)和方法(可用于特定容器实例)来表达这些算法。

1 STL和C++11

C++11对C++语言做了大量修改,C++11给STL新增了多个元素。首先,它新增了多个容器;其次,给旧容器新增了多项功能;第三,在算法系列中新增了一些模板函数。

1.1 新增的容器

C++11新增了如下容器:array、forward_list、unordered_st以及无序关联容器unordered_multiset、unordered_map和unordered_multimap。

在这里插入图片描述

1.2 对C++98容器所做的修改

C++对容器类的方法做了三项主要修改。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2 大部分容器都有的成员

所有容器都定义了表G.1列出的类型。在这个表中,x为容器类型,如vector<int>;T为存储在容器中的类型,如int。表G.1中的示例阐明了含义。

在这里插入图片描述
类定义使用typedef定义这些成员。可以使用这些类型来声明适当的变量。例如,下面的代码使用迂回的方式,将由string对象组成的矢量中的第一个”bonus“替换为”bogus“,以演示如何使用成员类型来声明变量。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所有的容器都还可以包含表G.2列出的成员函数或操作。其中,X是容器类型,如vector<int>,而T是存储在容器中的类型,如int。另外,a和b是类型为X的值;u是标识符;r是类型为X的非const值;rv是类型为X的非const右值,而移动操作是C++11新增的。

表G.2 为所有容器定义的操作

操作描述
X u创建一个名为u的空对象
X()创建一个空对象
X(a)创建对象a的拷贝
X u(a)u是a的拷贝(复制构造函数)
X u=au是a的拷贝(复制构造函数)
r=ar等于a的值(复制赋值)
X u(rv)u等于rv的原始值(移动构造函数)
X u = rvu等于rv的原始值(移动构造函数)
a=rvu等于rv的原始值(移动赋值)
(&a)->~X()对a的每个元素执行析构函数
begin()返回一个指向第一个元素的迭代器
end()返回一个指向超尾的迭代器
cbegin()返回一个指向第一个元素的迭代器
c end()返回一个指向超尾的迭代器
size()返回容器长度,即元素数量
maxsize()返回容器的最大可能长度
empty()如果容器为空,则返回true
swap()交换两个容器的长度
==如果两个容器的长度相同、包含的元素相同且元素排列的顺序相同,则返回true
!=a!=b返回!(a==b)

使用双向或随机迭代器的容器(vector、list、deque、array、set和map)是可反转的,它们提供了表G.3所示的方法。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.1 关于vector使用的补充
2.1.1 关于拷贝构造函数

有一个点很奇怪,有时间可以研究一下:

#include<iostream>
#include<vector>

using namespace std;

int main(void){
  vector<int> element;
  for(int i=0;i<10;i++){
    element.push_back(i);
  }
  
  
  vector< vector<int> > lista;
  for(int i=0;i<2;i++){
    lista.push_back(element);
  }
  lista[0][0]=100;
  cout<<lista[0][0]<<endl;
  cout<<lista[1][0]<<endl;

  return 0;
}

上面程序的输出是:

100
0

这个element不是指针吗,应该指向的是同一块内存空间?有点懵,为什么不变。

3 序列容器的其他成员

模板类vector、forward_list、list、deque和array都是序列容器,它们都包括前面列出的方法,但forward_list不是可反转的,不支持表G.3所示的方法。序列容器以线性顺序存储一组类型相同的值。如果序列包含的元素数是固定的,通常选择使用array;否则,应首先考虑使用vector,它让array的随机存取功能以及添加和删除元素的功能于一身。然而,如果经常需要在序列中间添加元素,应考虑使用list或forward_list。如果添加和删除操作主要是在序列两端进行的,应考虑使用deque。

表G.5 为序列容器定义的其他操作

操作描述
X(n,t)创建一个序列容器,它包含t的n个拷贝
X a(n,t)创建一个名为a的序列容器,它包含t的n个拷贝
X(i,j)使用区间[i,j]内的值创建一个序列容器
X a(i,j)使用区间[i,j)内的值创建一个名为a的序列容器
X(il)创建一个序列容器,并将其初始化为il的内容
a=il;将il的值复制到a中
a.emplace(p,args);在p前面插入一个类型为T的对象,创建该对象时使用与args封装的参数匹配的构造函数

待补充 898

在这里插入图片描述
表G.6列出了一些序列类(vector、forward_list、list和deque)都有的方法。

操作描述容器
a.back()返回*a.end()(最后一个元素)vector、list、deque
a.push_back(t)将t插入到a.end()前面vector、list、deque
a.push_back(rv)将rv插入到a.end()前面;可能使用移动语义vector、list、deque
a.pop_back()删除最后一个元素vector、list、deque
a.emplace_back(args)追加一个类型为T的对象,创建该对象时使用与args封装的参数匹配的构造函数vector、list、deque
a.push_front(t)将t的拷贝插入到第一个元素前面forward_list、list、deque
a.push_front(rv)将rv的拷贝插入到第一个元素前面;可能使用移动语义forward_list、list、deque
a.emplace_front()在最前面插入一个类型为T的对象,创建该对象时使用与args封装的参数匹配的构造函数forward_list、list、deque
a.pop_front()删除第一个元素forward_list、list
a[n]返回*(a.begin()+n)vector、deque、array
a.at(n)返回*(a.begin()+n);如果n>a.size,则引发out_of_range异常vector、deque、array

模板vector还包含表G.7列出的方法。其中a是vector容器,n是x::size_type型整数。

在这里插入图片描述
在这里插入图片描述

待补充 900

4 set和map的其他操作

Associative containers, of which sets and maps are models, have a Key template parameter and a Compare template parameter, which indicate, respectively, the type of the key used to order the contents and the function object, termed a comparison object, used to compare key values. For the set and multiset containers, the stored keys are the stored values, so the key type is the same as the value type. For the map and multimap containers, the stored values of one type (template parameter T) are associated with a key type (template parameter Key),and the value type is pair<const Key, T>.Associative containers have
additional members to describe these features,as listed in Table G.9.

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
表 G.10 为set、multiset、map和multimap定义的操作

操作描述

在这里插入图片描述
在这里插入图片描述

创建一个map的方式如下:

map<int,int> test;

判断map中是否存在一个key:

 m.count(key) == 0 ;
4.1 Unordered Associative Containers (C++11)

As mentioned earlier, the unordered associative containers (unordered_set, unordered_multiset, unordered_map,and unordered_multimap) use keys and hash tables to provide rapid access to data. (A hash function converts a key to an index value. For example, if the key were a string, the hash function could sum the numeric codes for the characters in the string and take that sum modulus 13, thus giving an index in the range 0–12.The unordered container would use 13 buckets to store strings.Any string with, say,an index of 4 would be placed in bucket 4. If you wished to search the container for a key, you would apply the hash function to the key and just search the bucket with the corresponding index. Ideally, you would have enough buckets that each one would contain only a few strings.可以删除)

The C++11 library provides a hash<Key> template that the unordered associative containers use by default. Specializations are defined for the various integer and floating point types, for pointers,and for some template classes, such as string.

Table G.11 lists types used for these containers.

在这里插入图片描述
In addition to the Table G.10 methods, the unordered associative containers require several more methods,as listed in Table G.12. In this table, X is an unordered associative container class, a is an object of type X, b is a possibly constant object of type X, a_uniq is an object of type unordered_set or unordered_map, a_eq is an object of type unordered_multiset or unordered_multimap, hf is a value of type hasher, eq is a value
of type key_equal, n is a value of type size_type,and z is a value of type float.As before, i and j are input iterators referring to elements of value_type, [i, j) is a valid range, p and q2 are iterators to a, q and q1 are dereferenceable iterators to a, [q1, q2) is a valid range, t is a value of X::value_type (which may be a pair),and k is a value of X::key_type.Also il is an initializer_list<value_type> object.

在这里插入图片描述

在这里插入图片描述

5 STL函数

STL算法库(由头文件algorithm和numeric支持)提供了大量基于迭代器的非成员模板函数。C++标准将算法分成四组:非修改式序列操作、修改式序列操作、排序和相关运算符以及数值操作(C++11将数值操作从STL移到了numeric库中,但这并不影响它们的用法)。序列操作(sequence operation)表明,函数将接受两个迭代器作为参数,它们定义了要操作的区间或序列。修改式(mutating)意味着函数可以修改容器的内容。

5.1 非修改式序列操作

在这里插入图片描述
在这里插入图片描述
5 find()

template<class InputIterator, class T>
InputIterator find(
	InputIterator first,
	InputIterator last,
	Const T& value
);

find()函数返回一个迭代器,该迭代器指向区间[first,last]中第一个值为value的元素;如果没有找到这样的元素,则返回last。

5.2 修改式序列操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

25 reverse
template<class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);

一个使用的例子:

#include<iostream>
#include<algorithm>

using namespace std;

int main(void){
  string x="abcde";
  reverse(x.begin(),x.end());
  cout<<x<<endl;
  return 0;
}

输出:

edcba
5.3 排序和相关操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.3.1 排序

首先来看看排序算法。

1 sort()

template<class RandomAccessIterator>
void sort(RandomAccessIterator first,RandomAccessIterator last);
template<class RandomAccessIterator,class Compare>
void sort(
	RandomAccessIterator first,
	RandomAccessIterator last,
	Compare comp
);

一个使用的具体例子:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(void){
  vector<int> v;
  for(int i=3;i>=0;i--){
    v.push_back(i);
  }
  sort(v.begin(),v.end());
  for(int i=0;i<4;i++){
    cout<<v[i]<<endl;
  }

  return 0;
}

//输出
// 0
// 1
// 2
// 3

sort()函数将[first,last)区间按升序进行排序,排序时使用值类型的<运算符进行比较。第一个版本使用<来确定顺序,而第二个版本使用比较对象comp

如果想要倒序排序,那么可以进行如下修改:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(void){
  vector<int> v;
  for(int i=3;i>=0;i--){
    v.push_back(i);
  }
  sort(v.begin(),v.end(),greater<int>());
  for(int i=0;i<4;i++){
    cout<<v[i]<<endl;
  }

  return 0;
}

待补充 915

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值