为什么 std::end() 返回的值会随着容器的变化而变化,而 std::begin() 则不会?
why do values returned by std::end() change as the container changes, but not with 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
——我want/expect的输出是0 1 2 3 4
。我猜想看这段代码 std::end
returns 是指向列表最后一个元素的迭代器,它被复制到 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
的doc:
Returns an iterator to the element following the last element of the
container, This element acts as a placeholder; attempting to access it
results in undefined behavior.
对于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;
}
我有一个要插入项目的 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
——我want/expect的输出是0 1 2 3 4
。我猜想看这段代码 std::end
returns 是指向列表最后一个元素的迭代器,它被复制到 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
的doc:
Returns an iterator to the element following the last element of the container, This element acts as a placeholder; attempting to access it results in undefined behavior.
对于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;
}