在回答如何进行自我复制的载体? 已经让我有点困惑迭代器失效。 有些文献说,“如果你使用INSERT,的push_back等考虑所有迭代器无效”。 那是明显的,它可能会导致其成长无效迭代器的矢量。 什么是特殊情况下,我知道那里将是足够的空间?
第一次尝试:
myvec.reserve(myvec.size()*3); //does this protect me from iterator invalidation?
vector<string>::iterator it = myvec.end();
myvec.insert(myvec.end(), myvec.begin(), it);
myvec.insert(myvec.end(), myvec.begin(), it);
经过一些优秀的答案,第二次尝试:
auto size = myvec.size();
myvec.reserve(size*3); //does this protect me from iterator invalidation?
myvec.insert(myvec.end(), myvec.begin(), myvec.begin()+size);
myvec.insert(myvec.end(), myvec.begin(), myvec.begin()+size);
经过优良的答案第三次尝试:
auto size = myvec.size();
myvec.reserve(size*3); //does this protect me from iterator invalidation?
back_insert_iterator< vector<string> > back_it (myvec);
copy (myvec.begin(),myvec.begin()+size,back_it);
copy (myvec.begin(),myvec.begin()+size,back_it);
本报价由约祖蒂斯‘C ++标准库参考’:
插入或删除元素无效引用以下元素引用,指针和迭代器。 如果插入引起的重新分配,这一切无效引用,迭代器和指针。
表明我的代码是安全的和定义的行为。 有没有在这个担保标准的一个通道?
过去最末端迭代器总是有点特别。 我会小心。 标准说,这(23.3.6.5):
如果没有重新分配情况,所有的迭代器和插入点之前引用保持有效。
这里的关键是“插入点之前”。 因为你原来it
不是将插入点之前(因为它是插入点),我不会行其上剩余的有效。
虽然这是事实,插入到载体中不会造成再分配只要容量不被超过,并且不会失效迭代以将插入点之前的元素(其可以说是的情况下end()
作为@KerrekSB指出出),表C ++ 11标准的100(段落23.2.3)指定为以下前提 a.insert(p,i,j)
函数序列容器:
[...]前:i和j不是迭代器成。 [...]
在你的情况,他们显然是,这让我觉得程序未定义行为。
迭代器不应该是无效的中期功能。 有观点认为,存储可以被重新定位不成立了,因为你不能使用realloc
与非平凡的构造函数的对象。 即使建设是不是一个问题,但它仍然不得不在最坏的情况下两次复制初始序列,在平均情况下否定任何好处。
点是,它没有任何意义实施这样说。 在alloc
, copy
, free
几乎可以肯定是做了,不管标准说什么。
因为这是安全的v.begin()
和v.end()
总是电流。
v.insert(v.end(), v.begin(), v.end());
v.insert(v.end(), v.begin(), v.end());
这不是。
vector<foo>::iterator i = v.begin();
vector<foo>::iterator j = v.end();
v.insert(v.end(), i, j);
v.insert(v.end(), i, j);
然而,自我插入可以靠不住的。 尝试下GCC以下。 自插入仅给出了如果有足够的内存可用不正确的结果(不知道这是一个bug)。
int main()
{
int position = 1, first = 2, last = 3;
// enforce error condition.
assert(position < first);
int size = 8;
// sanity check.
assert(first < last && last <= size);
std::vector<int> right, wrong;
// force resize during insertion.
right.reserve(size);
// avoid resize during insertion.
wrong.reserve(size + (last - first));
for ( int i = 0; i < size; i++ )
{
right.push_back(i);
wrong.push_back(i);
}
std::vector<int>::iterator i;
i = right.begin();
right.insert(i + position, i + first, i + last);
i = wrong.begin();
wrong.insert(i + position, i + first, i + last);
assert(right == wrong);
return 0;
}
注:上述意见适用于vector
具体而言,不是一般的容器。 同样,上述行为可能是一个错误的建议无关的标准,而执行难度为一个强大的自我插入的vector
。
文章来源: Does std::vector::insert() invalidate iterators if the vector has enough room (created through reserve)?