C++ 如何在干净的代码中向后遍历双向迭代器?
假设我有一个std::map,并希望对具有键X的项和具有更高键的每个项执行一些操作(请记住,这是一个有序映射)。代码显而易见且清晰:C++ 如何在干净的代码中向后遍历双向迭代器?,c++,c++11,containers,C++,C++11,Containers,假设我有一个std::map,并希望对具有键X的项和具有更高键的每个项执行一些操作(请记住,这是一个有序映射)。代码显而易见且清晰: auto iter = mymap.find(X); while (iter != mymap.end()) { process(*iter); iter++; } 或者,可能更好的是,std::for_each(mymap.find(X),mymap.end(),process) 但是,如果我的任务是对具有键X的项和每个具有较低键的项执行处理,
auto iter = mymap.find(X);
while (iter != mymap.end()) {
process(*iter);
iter++;
}
或者,可能更好的是,std::for_each(mymap.find(X),mymap.end(),process)
但是,如果我的任务是对具有键X的项和每个具有较低键的项执行处理,那么按照这个顺序,我找不到一个干净的编码模式来表达意图
auto iter mymap.find(x);
if (iter != mymap.end()) {
iter++; // Go forward...
while (iter != mymap.begin()) {
iter--; // ... so we can go backwards
process(*iter);
}
}
如果我不想按相反的顺序执行,那么可以很容易地递增std::map::find()返回的迭代器,然后使用std::for_each(mymap.begin(),incremented_iter,process)
双向迭代器不是反向迭代器,因此我不能在while()循环中使用mymap.rend()
在C++11中(或+14或+17中,因此我会有一些期待)是否有一种干净的方法可以做到这一点?您希望处理每个键为X或更低的项目,并从键为X的元素开始进行处理,然后向后进行。您可以在经过键X的第一个元素上使用reverse_iterator
,并创建一个反向迭代器,该迭代器指向您给出的元素之前的元素。然后可以迭代到“反向结束”:
为了更好的可读性,我通常保留一些帮助函数,以便从一对迭代器中创建一个“iterable对象”(可以使用.begin()
和.end()
调用该对象),因此我实际上会编写:
auto pastX = mymap.upper_bound(X);
// "IteRange" would return a "range-for-iterable" object from two iterators
for (auto&& elem : IteRange(std::make_reverse_iterator(pastX), mymap.rend()))
// Use elem
reverse_iterator
我错过的关键事实是将std::map::find()返回的双向迭代器转换为反向迭代器。我不能像你这里的代码那样简洁;我的上下文要求我在X实际上不在地图中时抛出。不过,这只是一张额外的支票,所以还是很干净的。我不认为你已经通过gist、GitHub或博客发布提供了帮助函数…@jdzions可能?请注意,这只有一个非常基本的要求,即有一个begin和end方法。我认为,在C++17中,还应该有一个size方法。
auto pastX = mymap.upper_bound(X);
// "IteRange" would return a "range-for-iterable" object from two iterators
for (auto&& elem : IteRange(std::make_reverse_iterator(pastX), mymap.rend()))
// Use elem