9.3 顺序容器操作

顺序元素与关联容器的区别在于两者组织元素的方式。

9.3.1 向顺序容器添加元素

除array外,所有标准库容器都提供灵活的内存管理。

----------------------------------- 向顺序容器(除array)添加元素的操作
c.push_back(t)
c.emplace_back(args) 在c的尾部创建一个值为t或由args创建的元素,返回void(forward_list不支持)
c.push_front(t)
c.emplace_front(args) 在c的头部创建一个值为t或由args创建的元素,返回void(vector和string不支持)
c.insert(p,t)
c.emplace(p,args) 在迭代器p指向的元素之前创建一个值为t或由args创建的元素。返回指向新添加元素的迭代器
c.insert(p,n,t) 在迭代器p指向的元素之前创建n个值为t的元素,返回指向新添加的第一个元素的迭代器
c.insert(p,b,e) 将迭代器b和e指定的范围内的元素插入到迭代器p指向的元素之前。b和e不能指向c中元素。返回指向新添加的第一个元素的迭代器。若范围为空,则返回p
c.insert(p,il) il是一个花括号包围的元素值列表。将这些给定值插入到迭代器p指向元素之前。返回指向新添加的第一个元素的迭代器。若列表为空,则返回p

forward_list有自己专版本的insert和emplace。

向一个vector或string添加元素可能引起整个对象存储空间的重新分配,重新分配对象的存储空间需要分配新的内存,并将元素从旧的空间移动到新的空间。

  • 使用push_back 容器中的元素与提供值的对象没有任何关联,容器元素是拷贝。
string word;
word.push_back('a');
//等价
word += 'a';
vector<string> container1;
deque<string> container2;
container1.push_back(word);
container2.push_back(word);
  • 使用push_front
list<int> ilist;
for(decltype(ilist.size()) i = 0; i != 4; ++i)
{
  ilist.push_front(i);
}
  • 在容器特定位置添加元素

某些容器不支持push_front,但对于insert操作并无类似的限制。

vector<string> svec;
list<string> slist;
svec.insert(svec.begin(), "hello");
slist.insert(slist.begin(), "hello");
//注意:vector插入除尾部外的位置会很慢
  • 插入范围内的元素
vector<string> svec;
list<string> slist;
vector<string> v = {"abc", "def", "ghi"};
svec.insert(svec.end(), 10, "hello");
svec.insert(svec.end(), v.end()-2, v.end());
svec.insert(svec.end(), {"abc, "def", "ghi"});
  • 使用insert的返回值
list<string> slist;
auto iter = slist.begin();
string word;
while(cin>>word)
{
  insert(iter, word);
}
  • 使用emplace操作
c.emplace_back("123-456", 25, 15.99);
c.push_back(Sales_data("123-456", 25, 15.99));

在调用emplace_back时,会在容器管理的内存空间直接创建对象,调用push_back则创建局部临时对象。