六一的部落格


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



顺序容器 添加元素 扩容
array X -
vector(string) O 有可能
deque O 有可能
list O -
forward_list O -

会改变容器大小

不一定需要扩容


容器对添加元素操作的支持

顺序容器 插入尾元素: push_back/emplace_back 插入首元素: push_front/emplace_front 指定位置插入元素: insert/emplace
vector(string) O X O; 移动元素会产生开销
deque O O O; 移动元素会产生开销
list O O O
forward_list X O; 可以通过首前迭代器完成 -; forward_list的insert和emplace是定制的

示例

1c.push_back(t);
2
3c.push_front(t);
1c.emplace_back(args);
2
3c.emplace_front(args);
4
5c.emplace(p, args);
1c.insert(p, t);
2
3c.insert(p, n, t);
4
5c.insert(p, b, e);
6
7c.insert(p, il);

区分添加元素操作

操作 使用参数构造新元素 新元素为给定元素的拷贝 支持插入单个元素 支持插入多个元素 支持任意指定位置插入元素 只支持首/尾插入元素
push_back/push_front - O O - - O
emplace_back/emplace_front O - O - - O
emplace O - O - O -
insert - O O O O -

是否需要移动元素

顺序容器 push_back/emplace_back push_front/emplace_front emplace/insert
vector(string) X - O; 非尾加需要
deque X X O; 非首/尾加需要
list X X X
forward_list - X -

push_back/push_front操作

返回void

-
push_back 插入尾元素
push_front 插入首元素
1c.push_back(t);
2
3c.push_front(t);

push_back操作

 1string word;
 2
 3while (cin >> word)
 4    container.push_back(word);        // container可以是vector,list,deque
 5
 6void pluralize(size_t cnt, string &word)
 7{
 8    if (cnt > 1)
 9        word.push_back('s');
10}
 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8    string isbn() const { return bookNo; }
 9    Sales_data& combine(const Sales_data&);
10    double avg_price() const;
11    string bookNo;
12    unsigned units_sold = 0;
13    double revenue = 0.0;
14};
15
16c.push_back(Sales_data("978-0590353403", 25, 15.99));
17// 构造临时对象,拷贝到容器

push_front操作

1list<int> ilist;
2
3for (size_t ix = 0; ix != 4; ++ix)
4    ilist.push_front(ix);
5
6// ilist = {3, 2, 1, 0};

emplace_back/emplace_front/emplace操作

返回void

  1. emplace系列操作在容器中直接构造元素

    传递给emplace系列操作的参数必须与元素类型的构造函数相匹配
  2. 使用emplace系列操作时,将参数传递给元素类型的构造函数,构造函数使用这些参数在容器管理的内存空间中直接构造元素

    使用push或者insert系列添加元素时,这些对象被拷贝到容器中
  3. emplace系列操作是新标准引入的3个新成员

emplace系列操作为emplace_back/emplace_front/emplace

-
emplace_back 新构造的元素作为尾元素插入
emplace_front 新构造的元素作为首元素插入
emplace 在指定位置插入新构造的元素
1c.emplace_back(args);
2
3c.emplace_front(args);
4
5c.emplace(p, args);

emplace_back操作

在容器中构造对象

 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8    string isbn() const { return bookNo; }
 9    Sales_data& combine(const Sales_data&);
10    double avg_price() const;
11    string bookNo;
12    unsigned units_sold = 0;
13    double revenue = 0.0;
14};
15
16// 使用默认构造函数
17c.emplace_back();
18
19c.emplace_back("978-0590353403", 25, 15.99);

emplace_front操作

 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8
 9    string isbn() const { return bookNo; }
10    Sales_data& combine(const Sales_data&);
11    double avg_price() const;
12    string bookNo;
13    unsigned units_sold = 0;
14    double revenue = 0.0;
15};
16
17
18// 匹配Sales_data(cosnt string &, unsigned, double)
19c.emplace_front("978-0590353403", 25, 15.99);

emplace操作

返回指向位置p的迭代器. p位置对应新添加的元素

  1. b和e分别为顺序容器的首迭代器和尾后迭代器

    指定位置p的范围为[b, e], 刚好覆盖容器当前可增加元素的所有位置
  2. [p, e)位置元素后移

    在p处构造新元素并插入
  3. 使用emplace操作,可以为vector(string)模拟emplace_front操作

    forward_list支持emplace_front,有自己的emplace版本
 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8    string isbn() const { return bookNo; }
 9    Sales_data& combine(const Sales_data&);
10    double avg_price() const;
11    string bookNo;
12    unsigned units_sold = 0;
13    double revenue = 0.0;
14};
15
16c.emplace(iter, "999-999999999");

insert操作

返回指向位置p的迭代器. p位置对应新添加的(第一个)元素

  1. b和e分别为顺序容器的首迭代器和尾后迭代器

    指定位置p的范围为[b, e], 刚好覆盖容器当前可增加元素的所有位置
  2. [p, e)位置元素后移

    从p处开始插入新元素
  3. 使用insert,可以为vector(string)模拟push_front

    forward_list有自己的insert版本

提供重载版本

  • 插入单个元素

    1c.insert(p, t);
  • 插入若干个相同元素

    1c.insert(p, n, t);
  • 插入多个元素,由迭代器范围给出

    [b, e)

    1c.insert(p, b, e);
  • 插入多个元素,由列表给出

    1c.insert(p, il);

n为0/[b, e)为空/il为空时,返回p


使用insert操作插入单个元素

1vector<int> ivec{0, 1, 2, 3, 5, 6, 7};
2 auto p = ivec.begin() + 4;
3 ivec.insert(p, 4);
4
5// ivec = {0, 1, 2, 3, 4, 5, 6, 7};

为vector模拟push_front

1vector<string> svec;
2
3svec.insert(svec.begin(), "Hello!");

为list模拟push_front

1list<string> slist;
2
3slist.insert(slist.begin(), "Hello!");
4// <=>
5// slist.push_front("Hello!");

使用insert操作插入若干个相同元素

1vector<int> ivec{0, 1, 2, 3, 7};
2auto p = ivec.begin() + 4;
3ivec.insert(p, 3, 0);
4
5// ivec = {0, 1, 2, 3, 0, 0, 0, 7};
1vector<string> svec;
2
3svec.insert(svec.end(), 10, "Anna");

使用insert操作插入多个元素, 由迭代器范围给出

迭代器不能指向本容器

1vector<int> ivec{0, 1, 2, 3, 7};
2vector<int> ivec2{4, 5, 6};
3auto p = ivec.begin() + 4;
4ivec.insert(p, ivec2.begin(), ivec2.end());
5
6// ivec = {0, 1, 2, 3, 4, 5, 6, 7};
1vector<string> v = {"quasi", "simba", "frollo", "scar"};
2list<string> slist;
3
4slist.insert(slist.begin(), v.end() - 2, v.end());
5// slist = {"frollo", "scar"};
6
7slist.insert(slist.end(), {"these", "words", "will", "go", "at", "the", "end"});
8// slist = {"frollo", "scar", "these", "words", "will", "go", "at", "the", "end"};

使用insert操作插入多个元素, 由列表给出

1vector<int> ivec{0, 1, 2, 3, 7};
2auto p = ivec.begin() + 4;
3ivec.insert(p, {4, 5, 6});
4
5// ivec = {0, 1, 2, 3, 4, 5, 6, 7};

使用insert的返回值

模拟push_front

 1list<string> lst;
 2
 3auto iter = lst.begin();
 4// <=>
 5// auto iter = lst.end();
 6// 列表为空时,begin和end的返回值一样
 7
 8string word;
 9while (cin >> word)
10    iter = lst.insert(iter, word);        // 每回都插入作为首元素
11
12// <=> 
13// lst.push_front(word);
14// 返回的是首元素的位置

顺序容器操作: 添加元素


顺序容器 添加元素 扩容
array X -
vector(string) O 有可能
deque O 有可能
list O -
forward_list O -

会改变容器大小

不一定需要扩容


容器对添加元素操作的支持

顺序容器 插入尾元素: push_back/emplace_back 插入首元素: push_front/emplace_front 指定位置插入元素: insert/emplace
vector(string) O X O; 移动元素会产生开销
deque O O O; 移动元素会产生开销
list O O O
forward_list X O; 可以通过首前迭代器完成 -; forward_list的insert和emplace是定制的

示例

1c.push_back(t);
2
3c.push_front(t);
1c.emplace_back(args);
2
3c.emplace_front(args);
4
5c.emplace(p, args);
1c.insert(p, t);
2
3c.insert(p, n, t);
4
5c.insert(p, b, e);
6
7c.insert(p, il);

区分添加元素操作

操作 使用参数构造新元素 新元素为给定元素的拷贝 支持插入单个元素 支持插入多个元素 支持任意指定位置插入元素 只支持首/尾插入元素
push_back/push_front - O O - - O
emplace_back/emplace_front O - O - - O
emplace O - O - O -
insert - O O O O -

是否需要移动元素

顺序容器 push_back/emplace_back push_front/emplace_front emplace/insert
vector(string) X - O; 非尾加需要
deque X X O; 非首/尾加需要
list X X X
forward_list - X -

push_back/push_front操作

返回void

-
push_back 插入尾元素
push_front 插入首元素
1c.push_back(t);
2
3c.push_front(t);

push_back操作

 1string word;
 2
 3while (cin >> word)
 4    container.push_back(word);        // container可以是vector,list,deque
 5
 6void pluralize(size_t cnt, string &word)
 7{
 8    if (cnt > 1)
 9        word.push_back('s');
10}
 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8    string isbn() const { return bookNo; }
 9    Sales_data& combine(const Sales_data&);
10    double avg_price() const;
11    string bookNo;
12    unsigned units_sold = 0;
13    double revenue = 0.0;
14};
15
16c.push_back(Sales_data("978-0590353403", 25, 15.99));
17// 构造临时对象,拷贝到容器

push_front操作

1list<int> ilist;
2
3for (size_t ix = 0; ix != 4; ++ix)
4    ilist.push_front(ix);
5
6// ilist = {3, 2, 1, 0};

emplace_back/emplace_front/emplace操作

返回void

  1. emplace系列操作在容器中直接构造元素

    传递给emplace系列操作的参数必须与元素类型的构造函数相匹配
  2. 使用emplace系列操作时,将参数传递给元素类型的构造函数,构造函数使用这些参数在容器管理的内存空间中直接构造元素

    使用push或者insert系列添加元素时,这些对象被拷贝到容器中
  3. emplace系列操作是新标准引入的3个新成员

emplace系列操作为emplace_back/emplace_front/emplace

-
emplace_back 新构造的元素作为尾元素插入
emplace_front 新构造的元素作为首元素插入
emplace 在指定位置插入新构造的元素
1c.emplace_back(args);
2
3c.emplace_front(args);
4
5c.emplace(p, args);

emplace_back操作

在容器中构造对象

 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8    string isbn() const { return bookNo; }
 9    Sales_data& combine(const Sales_data&);
10    double avg_price() const;
11    string bookNo;
12    unsigned units_sold = 0;
13    double revenue = 0.0;
14};
15
16// 使用默认构造函数
17c.emplace_back();
18
19c.emplace_back("978-0590353403", 25, 15.99);

emplace_front操作

 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8
 9    string isbn() const { return bookNo; }
10    Sales_data& combine(const Sales_data&);
11    double avg_price() const;
12    string bookNo;
13    unsigned units_sold = 0;
14    double revenue = 0.0;
15};
16
17
18// 匹配Sales_data(cosnt string &, unsigned, double)
19c.emplace_front("978-0590353403", 25, 15.99);

emplace操作

返回指向位置p的迭代器. p位置对应新添加的元素

  1. b和e分别为顺序容器的首迭代器和尾后迭代器

    指定位置p的范围为[b, e], 刚好覆盖容器当前可增加元素的所有位置
  2. [p, e)位置元素后移

    在p处构造新元素并插入
  3. 使用emplace操作,可以为vector(string)模拟emplace_front操作

    forward_list支持emplace_front,有自己的emplace版本
 1struct Sales_data
 2{
 3    Sales_data() = default;
 4    Sales_data(const string &s) : bookNo(s) {}
 5    Sales_data(cosnt string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n) {}
 6    Sales_data(istream &);
 7
 8    string isbn() const { return bookNo; }
 9    Sales_data& combine(const Sales_data&);
10    double avg_price() const;
11    string bookNo;
12    unsigned units_sold = 0;
13    double revenue = 0.0;
14};
15
16c.emplace(iter, "999-999999999");

insert操作

返回指向位置p的迭代器. p位置对应新添加的(第一个)元素

  1. b和e分别为顺序容器的首迭代器和尾后迭代器

    指定位置p的范围为[b, e], 刚好覆盖容器当前可增加元素的所有位置
  2. [p, e)位置元素后移

    从p处开始插入新元素
  3. 使用insert,可以为vector(string)模拟push_front

    forward_list有自己的insert版本

提供重载版本

  • 插入单个元素

    1c.insert(p, t);
  • 插入若干个相同元素

    1c.insert(p, n, t);
  • 插入多个元素,由迭代器范围给出

    [b, e)

    1c.insert(p, b, e);
  • 插入多个元素,由列表给出

    1c.insert(p, il);

n为0/[b, e)为空/il为空时,返回p


使用insert操作插入单个元素

1vector<int> ivec{0, 1, 2, 3, 5, 6, 7};
2 auto p = ivec.begin() + 4;
3 ivec.insert(p, 4);
4
5// ivec = {0, 1, 2, 3, 4, 5, 6, 7};

为vector模拟push_front

1vector<string> svec;
2
3svec.insert(svec.begin(), "Hello!");

为list模拟push_front

1list<string> slist;
2
3slist.insert(slist.begin(), "Hello!");
4// <=>
5// slist.push_front("Hello!");

使用insert操作插入若干个相同元素

1vector<int> ivec{0, 1, 2, 3, 7};
2auto p = ivec.begin() + 4;
3ivec.insert(p, 3, 0);
4
5// ivec = {0, 1, 2, 3, 0, 0, 0, 7};
1vector<string> svec;
2
3svec.insert(svec.end(), 10, "Anna");

使用insert操作插入多个元素, 由迭代器范围给出

迭代器不能指向本容器

1vector<int> ivec{0, 1, 2, 3, 7};
2vector<int> ivec2{4, 5, 6};
3auto p = ivec.begin() + 4;
4ivec.insert(p, ivec2.begin(), ivec2.end());
5
6// ivec = {0, 1, 2, 3, 4, 5, 6, 7};
1vector<string> v = {"quasi", "simba", "frollo", "scar"};
2list<string> slist;
3
4slist.insert(slist.begin(), v.end() - 2, v.end());
5// slist = {"frollo", "scar"};
6
7slist.insert(slist.end(), {"these", "words", "will", "go", "at", "the", "end"});
8// slist = {"frollo", "scar", "these", "words", "will", "go", "at", "the", "end"};

使用insert操作插入多个元素, 由列表给出

1vector<int> ivec{0, 1, 2, 3, 7};
2auto p = ivec.begin() + 4;
3ivec.insert(p, {4, 5, 6});
4
5// ivec = {0, 1, 2, 3, 4, 5, 6, 7};

使用insert的返回值

模拟push_front

 1list<string> lst;
 2
 3auto iter = lst.begin();
 4// <=>
 5// auto iter = lst.end();
 6// 列表为空时,begin和end的返回值一样
 7
 8string word;
 9while (cin >> word)
10    iter = lst.insert(iter, word);        // 每回都插入作为首元素
11
12// <=> 
13// lst.push_front(word);
14// 返回的是首元素的位置