【发布时间】:2013-05-12 14:41:37
【问题描述】:
在处理像 std::vector 这样的 C++ 标准库容器时,它们的基于范围的插入方法如何处理使用引用向量自身内容的迭代器的用户?
如果他们已经说vector::iterator,那么实现可以特例这种情况,但如果他们是最终导致访问向量的用户定义类型,向量如何处理保留这些迭代器在评估范围时有效吗?标准是否只是禁止引用范围内的向量?
举个简单的例子,考虑一个 value_type 为 size_t 的迭代器,取消引用它的结果是插入的向量的大小。
struct silly_iterator {
vector<std::size_t>* v;
unsigned number;
std::size_t operator*() { return v->size(); }
operator++() { --number; }
bool operator==(silly_iterator other) const { return number == 0; }
// other methods
};
std::vector<std::size_t> vec = { 3, 4, 5, 6, 7 };
vector.insert(vector.begin() + 2, silly_iterator(&vec, 10), silly_iterator());
这段代码执行后vec的内容是什么?
再举个例子,
struct silly_iterator {
std::vector<std::size_t>* v;
std::size_t operator*() { return 0; }
operator++() { --number; v->push_back((*v)[4]); }
bool operator==(silly_iterator other) const { return number == 0; }
// other methods
};
std::vector<std::size_t> vec = { 3, 4, 5, 6, 7 };
vec.insert(vec.begin() + 2, silly_iterator(&vec, 10), silly_iterator());
【问题讨论】:
-
标准没有禁止这样的事情,它只是说明了哪些迭代器何时失效。如果您的一个输入迭代器在插入过程中碰巧失效,那真是太可惜了,这么好的
vector被砸了... -
@n.m.:但它必须定义何时它们无效。
-
我现在没有可用的标准。我会假设它们在插入之前或期间的某个时间点失效。
-
我在stackoverflow.com/questions/10218223/… 有一个类似的问题。我认为这是未定义的行为,但有迹象表明这是 Microsoft VS 2010 特有的错误。
-
@MarkRansom:这是完全不同的,因为标准定义了您编写的内容应该可以工作,而我的问题是标准为此代码定义的内容(并且两个不同功能的规范非常不同)。
标签: c++