修改BOOST_FOREACH中向量的内容

Jam*_*ook 0 c++ foreach boost vector

这是一个关于BOOST_FOREACH如何检查它的循环终止的问题

cout << "Testing BOOST_FOREACH" << endl;
vector<int> numbers; numbers.reserve(8);
numbers.push_back(1); numbers.push_back(2); numbers.push_back(3);
cout << "capacity = " << numbers.capacity() << endl;
BOOST_FOREACH(int elem, numbers)
{
    cout << elem << endl;
    if (elem == 2) numbers.push_back(4); 
}
cout << "capacity = " << numbers.capacity() << endl;
Run Code Online (Sandbox Code Playgroud)

给出输出

Testing BOOST_FOREACH
capacity = 8
1
2
3
capacity = 8
Run Code Online (Sandbox Code Playgroud)

但是在循环中途插入的数字4呢?如果我将类型更改为列表,则将重复插入新插入的数字.如果需要重新分配,向量push_back操作将使任何指针无效,但是在此示例中不会发生这种情况.所以我猜的问题是为什么end()迭代器在使用向量时似乎只被评估一次(在循环之前),但在使用列表时有更动态的评估?

Eld*_*Eld 6

在封面下,BOOST_FOREACH使用迭代器遍历元素序列.在执行循环之前,结束迭代器被缓存在局部变量中.这称为吊装,这是一项重要的优化.但是,它假定序列的结束迭代器是稳定的.它通常是,但如果我们在迭代时通过添加或删除元素来修改序列,我们最终可能会在我们自己的petard上升起.

http://www.boost.org/doc/libs/1_40_0/doc/html/foreach/pitfalls.html

如果你不希望end()迭代器改变使用向量而不是保留.

http://www.cplusplus.com/reference/stl/vector/resize/

请注意,那么你不想要push_back而是使用operator [].但要小心走出界限.

  • 不确定std :: list使用什么作为end(),但没关系.但是sgi网站对这些列表说明了这一点:http://www.sgi.com/tech/stl/List.html"列表具有重要的属性,即插入和拼接不会使迭代器无效以列出元素,甚至删除也会失效迭代器指向被删除的元素." 并且end()是列表的迭代器,因此不应该对插入操作无效. (2认同)