std::vector事实上 std::string 也有 .at(), .front(), .back(), .push_back(x), .pop_back(), .clear() 等函数。C++ 标准库的各种设施是讲究统一性的。
练习:实现 Python 的 rstrip 函数,接受一个 std::string,返回它删去末尾的连续空白后的结果。
std::vector练习:实现 Python 的 rstrip 函数,接受一个 std::string,返回它删去末尾的连续空白后的结果。
std::string rstrip(std::string str) {
while (!str.empty() && std::isspace(str.back()))
str.pop_back();
return str;
}
在 C++17 下,这个 return str; 是不会产生拷贝的,不必担心。
std::vectorstd::vector 的增长策略考虑像这样连续 push_back n 次得到一个 vector 的代码:
std::vector<int> v;
for (int i = 0; i != n; ++i)
v.push_back(i);
vector 是如何做到快速增长的?
std::vectorstd::vector 的增长策略假设现在有一片动态分配的内存,长度为 i。
当第 i+1 个元素到来时,朴素做法:
i+1 的内存i 个元素拷贝过来但这需要拷贝 i 个元素。n 次 push_back 总共就需要
std::vectorstd::vector 的增长策略假设现在有一片动态分配的内存,长度为 i。
当第 i+1 个元素到来时,
2*i 的内存i 个元素拷贝过来而当第 i+2, i+3, ..., 2*i 个元素到来时,我们不需要分配新的内存,也不需要拷贝任何对象!
std::vectorstd::vector 的增长策略假设 push_back 的耗时是
使用 v.capacity() 来获得它目前所分配的内存的实际容量,看看是不是真的这样。
Lecture 8
read_string也是这个策略。
std::vectorstd::vector 动态增长带来的影响我们已经看到,改变 vector 的大小可能会导致它所保存的元素“搬家”,这会使得所有指针、引用、迭代器失效。
最直接的影响:下面的代码是 undefined behavior,因为基于范围的 for 语句本质上依赖于迭代器。
for (int i : vec)
if (i % 2 == 0)
vec.push_back(i + 1);
不要在用基于范围的 for 语句遍历容器的同时改变容器的大小!