六一的部落格


关关难过关关过,前路漫漫亦灿灿。




和顺序容器添加元素相比较

顺序容器 关联容器
指定位置插入元素: push_back/push_front/emplace_back/emplace_front/insert(p, val)/emplace(p, args) X; 关联容器元素的存储位置只与关键字有关,指定位置没有意义; 有序关联容器有时会给出指示位置
插入若干个相同元素: insert(p, n, t) X; 部分关联容器不允许关键字重复; 允许关键字重复的关联容器对相等关键字进行计数; 插入若干个相同元素没有意义
添加元素: insert(val) /emplace(args) O
添加迭代器范围给出的元素序列: insert(b, e) O
添加初始化列表给出的元素序列: insert({vals}) O

insert和emplace均为成员函数

map, set, unordered_map, unordered_set不允许关键字重复: 只有当元素的关键字不在容器中时才添加

有序关联容器的元素按关键字有序排列: 给出指示位置, 即从指示位置开始搜索新元素的存储位置, 可以省去一些开销


使用insert成员函数添加元素

向容器中添加单个元素或元素序列

  1. 接受元素类型对象
  2. 接受迭代器范围
  3. 接受初始化列表
  4. 接受元素类型对象和一个指示位置(指出从哪里开始搜索存储新元素的位置)

添加序列时: 对于一个给定的关键字,只有第一个带此关键字的元素被添加到容器中

 1c.insert(v);                    // v是value_type
 2
 3c.insert(b, e);
 4// b和e是迭代器,表示c::value_type类型值的范围
 5// 返回void
 6
 7c.insert(il);
 8// il是c::value_type类型值的列表(不允许精度丢失, 可以int转double, 不能double转int)
 9// 返回void
10
11c.insert(p, v);
12// p作为一个提示, 指出从哪里开始搜索新元素应该存储的位置; 返回一个迭代器,指向具有给定关键字的元素

示例

  1. set

    1vector<int> ivec = {2, 4, 6, 8, 2, 4, 6, 8};
    2set<int> set2;
    3set2.insert(ivec.cbegin(), ivec.cend());
    4set2.insert({1, 3, 5, 7, 1, 3, 5, 7});
  2. multimap

    1multimap<string, string> authors;
    2authors.insert({"Barth, John", "Sot-Weed Factor"});
    3authors.insert({"Barth, John", "Lost in the Funhouse"});

map的insert成员函数接受一个pair对象

1word_count.insert({word, 1});                                // 最优
2word_count.insert(make_pair(word, 1));                        
3word_count.insert(pair<string, size_t>(word, 1));            // 显式构造pair
4word_count.insert(map<string, size_t>::value_type(word, 1));

使用emplace成员函数添加元素

  1. 接受用以构造元素的参数: args用来构造元素

  2. 接受用以构造元素的参数和一个指示位置(指出从哪里开始搜索存储新元素的位置)

1c.emplace(args);                
2
3c.emplace(p, args);
4// p作为一个提示, 指出从哪里开始搜索新元素应该存储的位置; 返回一个迭代器,指向具有给定关键字的元素
5
6// 函数函数一个pair,first是迭代器,指向具有指定关键字的元素,second是bool值,指示插入是否成功

map的emplace成员函数使用参数构造pair对象

 1#include <iostream>
 2#include <map>
 3
 4using namespace std;
 5
 6int main()
 7{
 8    map<int, int> m{ {1, 1}, {0, 0} };
 9    m.emplace(3, 3);
10    auto elem =	s.at(3);
11    cout << elem << endl;
12
13    return 0;
14}

输出

3

insert和emplace的返回类型依赖于容器类型和参数


允许关键字重复的关联容器: 返回指向新元素的迭代器

每次都会添加新元素


不允许关键字重复的关联容器 + 使用insert添加序列: 返回void


不允许关键字重复的关联容器 + 使用insert/emplace添加单个元素: 返回键值对

不允许关键字重复的关联容器: map,set,unordered_map,unordered_set

insert和emplace的返回类型为键值对 pair<iterator, bool>

键值对的second成员为布尔类型 bool , 指示是否添加了新元素

second成员的值
true 添加了新元素, first成员指向新元素
false 未添加新元素, 关键字已存在; first成员指向具有给定关键字的元素

示例: 使用insert为map添加元素

 1map<string, size_t> word_count;
 2string word;
 3while (cin >> word)
 4{
 5    auto ret = word_count.insert({word, 1});
 6
 7    // <=>
 8    // pair<map<string, size_t>::iterator, bool> ret;
 9
10    if (!ret.second)  // 关键字已存在
11        ++ret.first->second;
12
13    // =>
14    // ++((ret.first)->second);
15    // ret的second指示添加元素成功与否
16    // ret的first为指向map元素的迭代器; 元素(键值对)的second成员为单词的出现次数, 初始值为1
17    // 添加元素不成功, 增加计数
18}

关联容器: 添加元素



和顺序容器添加元素相比较

顺序容器 关联容器
指定位置插入元素: push_back/push_front/emplace_back/emplace_front/insert(p, val)/emplace(p, args) X; 关联容器元素的存储位置只与关键字有关,指定位置没有意义; 有序关联容器有时会给出指示位置
插入若干个相同元素: insert(p, n, t) X; 部分关联容器不允许关键字重复; 允许关键字重复的关联容器对相等关键字进行计数; 插入若干个相同元素没有意义
添加元素: insert(val) /emplace(args) O
添加迭代器范围给出的元素序列: insert(b, e) O
添加初始化列表给出的元素序列: insert({vals}) O

insert和emplace均为成员函数

map, set, unordered_map, unordered_set不允许关键字重复: 只有当元素的关键字不在容器中时才添加

有序关联容器的元素按关键字有序排列: 给出指示位置, 即从指示位置开始搜索新元素的存储位置, 可以省去一些开销


使用insert成员函数添加元素

向容器中添加单个元素或元素序列

  1. 接受元素类型对象
  2. 接受迭代器范围
  3. 接受初始化列表
  4. 接受元素类型对象和一个指示位置(指出从哪里开始搜索存储新元素的位置)

添加序列时: 对于一个给定的关键字,只有第一个带此关键字的元素被添加到容器中

 1c.insert(v);                    // v是value_type
 2
 3c.insert(b, e);
 4// b和e是迭代器,表示c::value_type类型值的范围
 5// 返回void
 6
 7c.insert(il);
 8// il是c::value_type类型值的列表(不允许精度丢失, 可以int转double, 不能double转int)
 9// 返回void
10
11c.insert(p, v);
12// p作为一个提示, 指出从哪里开始搜索新元素应该存储的位置; 返回一个迭代器,指向具有给定关键字的元素

示例

  1. set

    1vector<int> ivec = {2, 4, 6, 8, 2, 4, 6, 8};
    2set<int> set2;
    3set2.insert(ivec.cbegin(), ivec.cend());
    4set2.insert({1, 3, 5, 7, 1, 3, 5, 7});
  2. multimap

    1multimap<string, string> authors;
    2authors.insert({"Barth, John", "Sot-Weed Factor"});
    3authors.insert({"Barth, John", "Lost in the Funhouse"});

map的insert成员函数接受一个pair对象

1word_count.insert({word, 1});                                // 最优
2word_count.insert(make_pair(word, 1));                        
3word_count.insert(pair<string, size_t>(word, 1));            // 显式构造pair
4word_count.insert(map<string, size_t>::value_type(word, 1));

使用emplace成员函数添加元素

  1. 接受用以构造元素的参数: args用来构造元素

  2. 接受用以构造元素的参数和一个指示位置(指出从哪里开始搜索存储新元素的位置)

1c.emplace(args);                
2
3c.emplace(p, args);
4// p作为一个提示, 指出从哪里开始搜索新元素应该存储的位置; 返回一个迭代器,指向具有给定关键字的元素
5
6// 函数函数一个pair,first是迭代器,指向具有指定关键字的元素,second是bool值,指示插入是否成功

map的emplace成员函数使用参数构造pair对象

 1#include <iostream>
 2#include <map>
 3
 4using namespace std;
 5
 6int main()
 7{
 8    map<int, int> m{ {1, 1}, {0, 0} };
 9    m.emplace(3, 3);
10    auto elem =	s.at(3);
11    cout << elem << endl;
12
13    return 0;
14}

输出

3

insert和emplace的返回类型依赖于容器类型和参数


允许关键字重复的关联容器: 返回指向新元素的迭代器

每次都会添加新元素


不允许关键字重复的关联容器 + 使用insert添加序列: 返回void


不允许关键字重复的关联容器 + 使用insert/emplace添加单个元素: 返回键值对

不允许关键字重复的关联容器: map,set,unordered_map,unordered_set

insert和emplace的返回类型为键值对 pair<iterator, bool>

键值对的second成员为布尔类型 bool , 指示是否添加了新元素

second成员的值
true 添加了新元素, first成员指向新元素
false 未添加新元素, 关键字已存在; first成员指向具有给定关键字的元素

示例: 使用insert为map添加元素

 1map<string, size_t> word_count;
 2string word;
 3while (cin >> word)
 4{
 5    auto ret = word_count.insert({word, 1});
 6
 7    // <=>
 8    // pair<map<string, size_t>::iterator, bool> ret;
 9
10    if (!ret.second)  // 关键字已存在
11        ++ret.first->second;
12
13    // =>
14    // ++((ret.first)->second);
15    // ret的second指示添加元素成功与否
16    // ret的first为指向map元素的迭代器; 元素(键值对)的second成员为单词的出现次数, 初始值为1
17    // 添加元素不成功, 增加计数
18}