c++ - 为什么 std::end() 返回的值会随着容器的变化而变化,而 std::begin() 则不会?
问题描述
我有一个std::list
我要插入项目的std::unordered_map
地方,我有一个我想将迭代器存储到插入到其中的元素的地方std::list
(我正在实现一个 LRU 缓存)。以下代码没有给我我期望的输出:
#include <list>
#include <unordered_map>
#include <iostream>
int main()
{
std::list<int> l;
std::unordered_map<int, std::list<int>::iterator> listItems;
for (int i = 0; i < 5; i++)
{
l.push_back(i);
listItems[i] = std::end(l);
}
for (int i = 0; i < 5; i++)
std::cout << *(listItems[i]) << " ";
std::cout << std::endl;
}
这里的输出是5 5 5 5 5
- 我想要/期望的输出是0 1 2 3 4
. 我会猜到这段代码std::end
返回一个迭代器到列表的最后一个元素,它被复制到 listItems[i] 中,但这显然不是正在发生的事情。我很困惑为什么将项目添加到列表会影响早期调用的结果std::end
但是,如果我将第一个循环更改为
for (int i = 0; i < 5; i++)
{
l.push_front(i);
listItems[i] = std::begin(l);
}
我得到了我期望的输出 - 0 1 2 3 4
。push_front
那么和push_back
和std::begin
和之间有什么区别std::end
解决方案
要获取最后一个元素的迭代器,可以通过:std::prev(std::end(l))
. 您的代码存储了结束迭代器并取消引用它,它是 UB。
和文档std::list::end
:_
返回容器最后一个元素之后的元素的迭代器,该元素充当占位符;尝试访问它会导致未定义的行为。
对于std::begin
,我们将迭代器获取到容器的第一个元素,它是安全的尊重它并获取相应的元素。
#include <iostream>
#include <list>
#include <unordered_map>
int main() {
std::list<int> l;
std::unordered_map<int, std::list<int>::iterator> listItems;
for (int i = 0; i < 5; i++) {
l.push_back(i);
listItems[i] = std::prev(std::end(l));
}
for (int i = 0; i < 5; i++) std::cout << *(listItems[i]) << " ";
std::cout << std::endl;
}
推荐阅读
- c - 对 BSP_LCD_Init 的调用永远不会返回。卡在 HAL_DSI_shortwrite
- java - HyperLoglog Spring 关键操作
- html - 多个结果的 XPath 字符串函数?
- c# - 如何检测项目何时添加到 UWP 应用程序中的 ListView 或从 ListView 中删除?
- reactjs - 将 create-react-app 部署到 heroku 时找不到应用程序
- c# - CheckSignature 返回错误
- ios - Xamarin IOS 自定义控件属性不显示
- python - pylatex 添加水平线
- c - 为什么不能将 int (*p)[] 用作 C 函数的参数?
- performance - 如果发生丢包事件,Jmeter 是否会重新传输请求?