我想我知道这个问题的答案,但我希望能进行一次理智检查。
迭代器无效是否适用于 std::back_insert_iterators?
#include <cassert>
#include <iterator>
#include <vector>
int main() {
auto v = std::vector<int>{ 0, 1, 2 };
auto iter = std::back_inserter(v);
*iter++ = 3;
v.clear(); // invalidates iterators, but
*iter++ = 4; // back_insert_iterator is special?
assert(v.size() == 1 && v[0] == 4);
return 0;
}
这段代码对我来说是可行的,因为我的供应商提供的 std::back_insert_iterator 实现不包含迭代器(或指针或引用)。它只是调用容器的 push_back 方法。
但是标准是否要求实现该功能?其他供应商的 back_insert_iterator 是否可以保存并维护一个尾端迭代器,以便与容器的 insert 方法调用一起使用?这似乎可以满足要求。当然,这种差异在于它容易失效。
我知道 cppreference.com 不是权威的,但是它比标准更容易访问。
[向量的 clear 方法] [i] 使引用所含元素的任何 ... 迭代器无效。任何超出末尾的迭代器也将失效。 [ cppreference.com,重点补充]
std::back_insert_iterator 可能是末尾迭代器的典型代表。
根据[back.insert.iterator]
我们可以看到,迭代器获取一个指向容器的指针,然后
push_back
直接在容器上调用,因此不存在 UB 的可能性。