容器适配器
关于emplace
,在C++11中值得说明的是:
容器的插入操作会涉及到两次构造,首先是临时对象的初始化构造;接着在插入的时候复制一次,会触发拷贝构造;最后释放临时对象。但是很多时候我们并不需要两次构造带来效率的浪费,希望在插入时直接构造。C++11标准已经新增了emplace语法来提升效率。容器的emplace类似insert,emplace_back类似push_back,在开发过程中应该尽量使用
emplace/emplace_back
进行插入。
顺序容器
关于clear
,值得说明的是:
- clear是从容器中擦除所有元素,但所申请的内存不会释放,即capacity() 不变。
- 可使用
vector<T>().swap(x)
完成释放内存的操作,原理是生成一个空的 vector 容器,通过交换函数swap,使得x离开其自身的作用域,从而强制释放所占的内存空间。- 也可使用
vector<T>(x).swap(x)
,等效于shrink_to_fit
,去除多余容量。
关联容器
- 只能用迭代器 (不断用变量值来递推新值,相当于指针) 操作元素,不支持使用下标运算符;
- 插入或删除操作后迭代器不会失效,指向被删除节点的迭代器失效;无序关联容器另作讨论;
- set/multiset 元素升序排列;map/multimap 按键值升序排列
映射容器 map
- map 即“键值对”容器,提供了“一对一”的映射关系. 其中存放的是
pair
对象,不允许有重复键值,构造时需要指定key与value的模板/类型, 容器内部自动按键值排序 - multimap 则是“一对多”的多映射容器,这里不做介绍
pair
是具有两个模板参数的模板类,如pair<string, int> s1("zhangsan", 25);
其具有两个属性s1.first
,s1.second
构造函数与初始化
定义空map
map<T1, T2> myMap;
map<T1, T2> newMap(myMap);
增加
operator[]
insert() - make_pair()
insert() - pair()
map<string, int> myMap;
myMap.insert(pair<string, int>("zhangsan", 25));
myMap["lisi"] = 26;
myMap.insert(make_pair("wang",27));
myMap
容器内部自动排序,见如下输出:
索引
- 不建议使用
operator[]
进行索引,因为如果键值不存在, 则会添加并设value=0
,无法返回正确索引结果 - 查找元素是否存在则使用
count()
方法,如果存在就返回1,否则返回0,无其他值 - 索引键值则使用
find()
方法,返回的是迭代器/pair指针变量,如果没找到就返回迭代器map.end()
auto idx = myMap.find("lee");
auto cnt = myMap.count("lee");
if(idx==myMap.end())
{
cout << "count = " << cnt << endl;
cout << "Not Found" << endl;
}
else
{
cout << "count = " << cnt << endl;
printf("key:value is (%s,%d)", idx->first.c_str(), idx->second);
}
删除
erase(key)
删除键值key,不报错,一律返回0erase(iterator_it)
删除第it个键值对,返回该位置最新元素的迭代器,原迭代器it已无效;erase(iterator_a, iterator _b)
删除 [a, b) 之间的键值对, 返回a位置最新元素的迭代器