cpp 容器避坑指南
使用 cpp 中常用容器时,的注意事项。
不要保存 end 返回的迭代器
当我们添加或删除 vector
或 string
的元素后,或在 deque
中首元素之外任何位置添加或删除元素后,原来 end
返回的迭代器总是会失效。因此,添加或删除元素的循环程序必须反复调用 end
,而不能在循环之前保存 end
返回的迭代器,一直当做容器末尾使用。
std::map 遍历删除元素
对容器进行增、删元素操作,可能会使迭代器失效。关于这一点,复习 《C++ Primer》 P315
正确的写法:(只需要记住正确的写法,其他的即便不是错的也是不规范的)
C++11 标准下,使用 erase()
返回值更新迭代器:返回值 Iterator following the last removed element.
1 | // erase all odd numbers from c |
C++11 之前,erase()
成员没有返回值。怎么遍历删除自行 Google 吧
C++11 之前
顺序容器的 erase()
操作返回指向删除的(最后一个)元素之后位置的迭代器。
map.erase()
有 3 个重载:
1 | ??? erase ( iterator position ); |
在 C++11 之前返回 iterator
的 erase()
是不符合 STL 标准的
1 | void erase( iterator pos ); (until C++11) |
vector 地址
vector 地址、vector 首元素地址以及 vector::data()
的返回值
后两者相等,但和容器地址是两码事。
1 | vector<int> ha = {1, 2, 3}; |
参考 :https://stackoverflow.com/a/14825318/6728820
迭代器
迭代器能递加递减,能加一减一吗?
随机访问迭代器 (RandomAccessIterator)是可以的。顺序容器 std::vector
是随机访问迭代器。
http://zh.cppreference.com/w/cpp/concept/RandomAccessIterator
但双向迭代器 (BidirectionalIterator)是不可以的。关联容器 std::set
std::map
、顺序容器std::list
是双向迭代器。
http://zh.cppreference.com/w/cpp/concept/BidirectionalIterator
更多信息请查看:迭代器
http://zh.cppreference.com/w/cpp/iterator/advance
http://zh.cppreference.com/w/cpp/iterator/next
两者的区别:https://stackoverflow.com/questions/15017065/whats-the-difference-between-stdadvance-and-stdnext