C++ 如何在干净的代码中向后遍历双向迭代器?

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的项和每个具有较低键的项执行处理,

假设我有一个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);
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