【发布时间】:2021-03-18 20:21:21
【问题描述】:
std::map.rbegin() 的反向迭代器返回包含std::map 中最大 key_type 的元素的位置。
可以使用map.rbegin() 返回的位置访问具有最大 Key 的元素,如下所示:map.rbegin()->first
但是map.rbegin()返回的位置不能用来擦除这个元素。
为什么我可以访问但不能删除相同的位置?
std::map <unsigned int, std::string> map;
map.emplace(5, "aaa");
map.emplace(7, "bbb");
map.emplace(3, "ccc");
cout << map.rbegin()->first << " : " << map.rbegin()->second << endl; //Reverse iterator works for accessing the element
map.erase(map.rbegin()); //Erase the largest element in the map - Error C2664 converting argument 1 from 'std::reverse_iterator<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>>' to 'std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>'
map.erase(std::prev(map.end())); //Erase the largest element in the map - WORKS
map.erase(std::prev(map.rbegin().base())); //Erase the largest element in the map - WORKS
在我看来,如果一个函数/方法需要一个迭代器来获得只有一个位置,那么它应该不不管它是哪种迭代器。 如果该迭代器描述的不仅仅是一个位置(例如方向,也是......),事情会有所不同
注意:我没有问“How to call erase with a reverse iterator?”,我在代码的最后一行提供了这个操作的解决方案。
我在问为什么我不能用反向迭代器擦除。也就是说,如果 STL 只需要使用它来获取要擦除的一个元素的位置,为什么不简单地将 std::map::reverse_iterator 转换为 std::map:iterator。
【问题讨论】:
-
简单地说,
std::map::erase没有反向迭代器的重载。它接受map::iterator、map::const_iterator和map::key_type。这些都不是反向迭代器类型。 -
一个“混搭”接口很容易出错,如果每个函数都需要在反向和“正常”迭代器上重载,它会使库变得非常复杂。 (一个有四个迭代器参数的函数可能需要十六个重载,如果你没有提供所有的重载,至少会有一个人会因为没有包含他们想要的组合而生气。)
-
它并不能真正解决你的问题,但是反向迭代器有一个
base函数,它返回一个正向迭代器 + 1。(map.rbegin().base() == map.end()) -
@super TIL。非常有用的功能,谢谢。
-
我看到你已经编辑了你的问题以链接到“如何”目标,所以我也添加了一个“为什么”目标。不幸的是,“为什么”目标已作为“如何”目标的欺骗而被关闭,而“为什么”目标的现有答案并不能真正回答这个问题。
标签: c++ iterator c++17 c++-standard-library reverse-iterator