STL(标准模板库)快速入门及函数汇总

为什么用STL

STL标准模板库(Standard Template Library)是每位C++都无法回避的库,但是有点复杂,如果你仅想快速会用,就是快速掌握80%的常用功能,这个文章值得你阅读,首先看下为什么要用STL:

未来代码的维护者学习你的版本的设计是否容易?
你的版本有多大可能性适用于 10 年之后的一个新平台?
你的版本有多大可能性适用于未来的应用?
你的版本有多大可能性能与用标准库编写的代码互操作?
你投入到优化和测试中的精力有多大可能性能与设计和实现标准库的投入相提并论?

STL框架

STL六大组件包括容器(container)、分配器(allocator)、算法(algorithm)、迭代器(iterator)、适配器(adapter)和仿函数(functor).我们常用的是容器与迭代器,把这两部分掌握,可以应付大部分的任务.

容器(containers)部分,STL的一个重要组成部分,涵盖了许多数据结构,比如前面曾经提到的链表,还有:vector(类似于大小可动态增加的数组)、queue(队列)、stack(堆栈)……。string也可以看作是一个容器,适用于容器的方法同样也适用于string。

迭代器(iterators)部分,STL的一个重要组成部分,如果没有迭代器的撮合,容器和算法便无法结合的如此完美。事实上,每个容器都有自己的迭代器,只有容器自己才知道如何访问自己的元素。它有点像指针,算法通过迭代器来定位和操控容器中的元素。

容器

        STL容器大体分为序列容器,关联容器和无序容器.看如下图:

Vector:模塑出一个动态数组.是有序的集群.

Deques:也是动态数组,只是头尾两端都可以插入删除.

List是使用双向链表管理元素.

Set/Multiset:根据特定的排序准则,自动将元素排序.Multiset允许重复,Set不允许

Map/Multimap将键值/实值对当作元素,进行管理.它可根据key的排序准则自动将元素排序.multimaps允许重复,maps不允许,

至于每种容器的能力差异请参考<C++标准程序库>表6.33

容器的函数比对表

VectorMaps及
Multimaps
DequesListSets
Multisets
构造,拷贝和解构
c产生一个空的VVVVV
c(op)以op排序准则XVXXV
c1(c2)产生c2副本VVVVV
c(n)产生n个元素,每个元素以默认构造初始化VXVVX
c(n,elem)产生nge元素,每个元素都是elem副本VXVVX
c(beg,end)以区间内的元素产生VVVVV
c(beg,end,op)以op排序,利用区间内元素产生XVXXV
非变动性操作
c.size()返回当前的元素数量VVVVV
c.empty()等同于size()==0VVVVV

c.max_

size()

返回可容纳的元素最大数量VVVVV
capacity()

返回重新分配空间所能容纳的元素

最大数量

VXXXX
reserve()如果容量不足,扩大值VXXXX

c1  c2

比大小

VVVVV
赋值
c1 = c2将c2的全部元素赋值给c1VVVVV

c.assign

(n,elem)

复制n个elem,赋值给cVXVVX

c.assign

(beg,end)

将区间内的元素赋值给cVXVVX

c1.swap

(c2)

将c1和c2元素互换VVVVV

swap

(c1,c2)

同上,此为全局变量VVVVV
元素存取
c.at(idx)返回索引idx所表示的元素Vp->firstVXX
c[idx]

返回索引idx所表示的元素,

无范围检查

Vp->secondVXX
c.front()

返回第一个元素,

不检查第一个元素是否存在

VXVVX
c.back()

返回最后一个元素,

不检查最后一个元素是否存在

VXVVX
迭代器相关函数
c.begin()

返回一个随机存取迭代器,

指向第一个元素

VVVVV
c.end()

返回一个随机存取迭代器,

指向最后最后元素的下一个位置

VVVVV
c.rbegin()

返回一个逆向迭代器,

指向你想迭代器的第一个元素

VVVVV
c.rend()

返回一个你想迭代器,指向逆向迭代器

的最后元素的的下一个位置

VVVVV
insert和remove元素
c.insert()

插入一个元素副本,

map:c[key]=value 也可以实现插入元素

VVVVV

c.push_

back(elem)

在尾部添加一个elem副本VXVVX

c.pop_

back()

移除最后一个元素(但不回传)VXVVX

c.push_

front(elem)

在头部插入elem的一个副本XXVVX

c.pop_

front()

移除头部元素XXVVX

c.erase

(pos)

移除pos位置或区间所有元素VVVVV

c.resize

(num)

将元素数量改为numVXVV
c.clear()移除所有元素VVVVV

c.remove

(val)

移除所有其值为val的元素XXXV

c.remove

_if(op)

移除所有"造成op(elem)结果为true"

的元素

XXXV
特殊的搜寻动作
count(key)返回"键值等于key"的元素个数XVXXV
find(key)

返回"键值等于key"的第一个元素

找不到返回end()

XVXXV

lower_bound

(key)

返回"键值为key"之元素的第一个可安插

位置,也就是"键值>=key"的第一个元素位置

XVXXV

uper_bound

(key)

返回"键值为key"之元素的最后一个可安插

位置,就是"键值>=可以"的第一个元素位置

XVXXV

equal_range

(key)

返回"键值为key之元素的第一个可安插

位置和最后一个可安插位置,

就是"键值==key"的元素区间

XVXXV
Splice 函数
c.unique()

如果存在若干相邻而数值相等的元素,

就移除重复元素,只留下一个

XXXVX

c1.splice

(pos,c2)

将c2内的所有元素转移到c1之内,

迭代器pos之前

XXXVX
c.sort()以operator<为原则,对所有元素排序XXXVX

c1.merge

(c2,op)

假设c1和c2容器都包含op()原则下的已序元素,将c2的全部元素转移到c1,

并保证合并后的list仍未已序

XXXVX
c.reverse()将所有元素反序XXXVX

类模板实例化

        数据的类型也可以通过参数来传递,在函数定义时可以不指明具体的数据类型,当函数 调用时,编译器根据传入的实参自动推断数据类型。——这就是类型的参数化(把类型 定义为参数),

这就是类模板的定义

template <class Key,   
    class Type,   
    class Traits = less<Key>,   
    class Allocator=allocator<pair <const Key, Type>>>  
class map;  

map模板实例化

std::map < int , int > m_pSetValue;

第一个int就是对key的实例化,第二个int就是对Type的实例化.

Pair结构

一种结构,该结构提供了将两个对象视为单个对象的的功能。

make_pair()是一种可用来构造 pair 类型对象的模板函数,其中,组件类型将根据作为参数传递的数据类型自动进行选择。函数原型:

template <class T, class U>
    pair<T, U> make_pair(T& Val1, U& Val2);
    pair<T, U> make_pair(T& Val1, U&& Val2);
    pair<T, U> make_pair(T&& Val1, U& Val2);
    pair<T, U> make_pair(T&& Val1, U&& Val2);

参数
Val1
用于初始化第一个 pair 元素的值。
Val2
用于初始化第二个 pair 元素的值。
返回值
所构造的配对对象:pair<T,U>(Val1, Val2)
make_pair 的优势之一在于要存储的对象类型由编译器自动确定,而不必显式指定.

以下为pair例程

#include <utility>
#include <map>
#include <iomanip>
#include <iostream>

int main( )
{
   using namespace std;

   pair <int, double> p1 ( 10, 1.1e-2 );//constexpr pair(const T1& Val1,const T2& Val2);

   pair <int, double> p2;//constexpr pair();
   p2 = make_pair ( 10, 2.22e-1 );//类型编译器自动确定

   // Making a copy of a pair
   pair <int, double> p3 ( p1 );//pair(const pair&)

   cout.precision ( 3 );
   cout << "The pair p1 is: ( " << p1.first << ", "
        << p1.second << " )." << endl;
   cout << "The pair p2 is: ( " << p2.first << ", "
        << p2.second << " )." << endl;
   cout << "The pair p3 is: ( " << p3.first << ", "
        << p3.second << " )." << endl;
}

容器的实用例子

        

main()
{
        std::vector<unsigned char> Buffer;// vector实例化
		unsigned char *data = "hello STL";
		for (int i = 0; i < strlen(data); i++) {
			//先添加到缓冲区中
			Buffer.push_back(data[i]);//vector尾部添加一个字符元素
        }
		std::string Mystring(Buffer.begin(), Buffer.end());//用这个构造函数template <class InputIterator> basic_string(InputIterator first,InputIterator last);
		Buffer.clear();
        printf("%s",Mystring);
		delete[] data;
		data = NULL;
}
main()
{
    std::map < int , int > m_pSetValue;//创建一个map容器,
    m_pSetValue[1] = 10;//通过[]直接元素存取
	std::map < int, int > ::iterator it = m_pSetValue.begin();
	int addr = it->first;
	int value = it->second;
	m_pSetValue.erase(it);
	return 0;
}
main()
{
    map<pair<int,int>, Info1*>::iterator it1;//创建迭代器.
    for (it1 = Map1.begin(); it1 != Map1.end(); it1++)//遍历整个Map1
    {
		pair<int, int> pairIndex = make_pair(it1->first, it1->second);
		map<pair<int, int>, Info*> ::iterator it = InfoMap.find(pairIndex);
		Info *pInfo = NULL;
		if (it != InfoMap.end())//找到了
		{
			pInfo = it->second;//把
		}
		else//没找到
		{
			pInfo = new LogInfo;
			pInfo->value1= it1->first;
			pInfo->value2= it1->second;
			InfoMap[pairIndex] = pInfo;//map的[]操作
		}
        pInfo->value3 = 6;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值