插入后的 std::list 结束迭代器
在 std::list 中,容器内的插入不应使迭代器无效,但它是如何实现的呢?例如,我有一个列表并插入一个值:
std::list<int> list;
list.push_back(12);
然后我得到结束迭代器:
auto end = list.end();
auto it = --end;
现在结束应该指向插入的元素。当我保留结束迭代器并进行另一次插入时会发生什么? --end 仍会指向 12 或新插入的值吗?
编辑1:
我用以下程序对此进行了测试:
#include <iostream>
#include <string>
#include <list>
int main()
{
std::list<int> list;
list.push_back(12);
auto end = list.end();
auto it = std::prev(end);
std::cout << *it << std::endl;
list.push_back(13);
it = std::prev(end);
std::cout << *it << std::endl;
it = std::prev(end);
std::cout << *it << std::endl;
}
这给了我 12 13 13 作为结果,我不明白,因为我在第二次插入后没有编辑结束迭代器。这意味着容器可以访问push_back内部的迭代器内部?
In std::list an insertion inside the container should not invalidate an iterator but how is that implemented? For example I have a list and insert one value:
std::list<int> list;
list.push_back(12);
Then I get the end iterator:
auto end = list.end();
auto it = --end;
Now end should point to the inserted element. What happens when I keep the end iterator and do another insertion? Will --end still point to 12 or to the new inserted value?
Edit1:
I tested this with the following program:
#include <iostream>
#include <string>
#include <list>
int main()
{
std::list<int> list;
list.push_back(12);
auto end = list.end();
auto it = std::prev(end);
std::cout << *it << std::endl;
list.push_back(13);
it = std::prev(end);
std::cout << *it << std::endl;
it = std::prev(end);
std::cout << *it << std::endl;
}
This gives me 12 13 13 as result which I don't understand because I did not edit the end iterator after the second insertion. This means the container has access to the iterator internals inside push_back?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
结束迭代器不会被
push_back
失效*,这意味着它将保留指向末尾。 (在这种情况下,您可以将其视为始终结束的哨兵节点的迭代器)*另一方面 std::vector 确实有一些使结束迭代器无效的操作
The end iterator is not invalidated by
push_back
*, which means it would keep point to the end. (in this case you can think it as a iterator to a sentinel node that's always the end)*on the other hand std::vector does have some operation that invalidate end iterator
--end
修改迭代器,使其指向第二个元素插入前后的12。如果保留结束迭代器而不对其进行修改,它仍然是第二次插入之前和之后经过最后一个元素的迭代器。
--end
第二次将是 UB,因为在第一次递减之后它指向第一个元素。但如果您没有修改结束迭代器,那么第一个
--end
将生成一个指向最后一个元素的迭代器。例子:
--end
modifies the iterator, so it points to the 12 before and after the insertion of the second element.If you had kept the end iterator without modifying it, it would still be the iterator to one past the last element before and after the second insertion.
--end
second time would be UB because after the first decrement it points to the first element.But if you had not modified the end iterator, then the first
--end
would produce an iterator to the last element.Example: