【发布时间】:2016-02-26 03:56:01
【问题描述】:
#include <iostream>
#include <map>
int main(int argc, char** argv)
{
std::map<int, int> map;
map.emplace(1, 1);
auto reverse_iter = map.rbegin();
std::cout << reverse_iter->first << ", " << reverse_iter->second << std::endl;
map.emplace(2, 2);
std::cout << reverse_iter->first << ", " << reverse_iter->second << std::endl;
return 0;
}
打印出来:
1, 1
2, 2
根据标准,这真的应该发生吗?我没有接触 reverse_iter,但它指向的值正在改变。我认为 std::map 中的迭代器应该可以安全地防止插入。然而,它似乎决定 reverse_iter 不是一直指向我告诉它的值,而是“此时此刻地图末端发生的任何事情”。
更新:更多信息,以防万一:前向迭代器似乎不会发生这种情况(在我似乎能找到的任何情况下),我的 gcc 版本是 5.1.1-4。
【问题讨论】:
-
被“无效”和指向新数据不是一回事,是吗?它是指向容器中最后一对的有效指针。那对恰好发生了变化。
-
前向迭代器不会发生。将 rbegin 替换为 begin 并将 (2, 2) 替换为 (0, 0)。再说一次,这是否符合标准?因为它真的出乎意料,这是肯定的。
-
对,你放在地图上的第一件事不会改变。但是你做的最后一件事会。
-
地图中的一切都没有改变——迭代器指向的东西正在改变,而我没有接触迭代器。为什么?符合那个标准吗?迭代器被设计为像一个指针 - 你将它指向某个东西,它会一直指向那里并保持有效,直到你将它指向其他东西或者它变得无效。事实上,前向迭代器似乎就是这样。但不能逆转。这有什么意义?在任何类型的非常量上下文中使用反向迭代器都是一个大问题。
-
没有迭代器失效;您的
reverse_iterator包含的常规iterator是end()迭代器,即使在emplace之后仍然有效。当您取消引用reverse_iterator时,它会递减end()迭代器并取消引用结果,从而为您提供您看到的输出。