C ++向后迭代容器N个步骤

时间:2019-06-06 09:51:05

标签: c++ list reverse-iterator

在C ++中,我可以使用reverse_iterator向后循环容器元素,例如list

如何迭代一定数量的元素?还没到开始?这段代码有效,但是我觉得有更好的方法。

std::list<int> mylist{1,2,3,4,5};
int cnt = 3;
for (auto rit = mylist.rbegin(); rit != mylist.rend(); ++rit) {
    if (cnt == 0) break;
    std::cout << *rit << " ";
    --cnt;
}

预期输出{5, 4, 3}

3 个答案:

答案 0 :(得分:4)

您可以如下调整循环:

for (auto rit = mylist.rbegin(); rit != std::next(mylist.rbegin(), 3); ++rit)
{
   std::cout << *rit << " ";
}

但是请注意,为了使此功能可靠地工作,您需要检查列表的大小至少为3,或者像std::next一样将参数调整为const auto n = std::min<std::size_t>(3, mylist.size());

使用C ++ 20,您应该可以使用(显然未经测试)

#include <ranges>

for (int n : mylist | std::ranges::reverse_view | std::ranges::take_view(3))
  std::cout << n << "\n";

这使大小测试变得多余,因为take_view受范围大小限制(它在内部执行此检查)。

答案 1 :(得分:4)

  

还没开始吗?

如果可以保证,那么

std::copy_n(mylist.rbegin(), 3, std::ostream_iterator<int>(std::cout, " "));

或者更安全

std::copy_n(mylist.rbegin(), std::min(mylist.size(), std::list<int>::size_type(3)), std::ostream_iterator<int>(std::cout, " "));

LIVE

答案 2 :(得分:2)

我不会在循环体中增加/减少和检查条件,而是将其放在您最期望的位置:

std::list<int> mylist{1,2,3,4,5};
int cnt = 3;
for (auto rit = mylist.rbegin(); rit != mylist.rend() && cnt > 0; ++rit,--cnt) {
    std::cout << *rit << " ";
}

例如,您现在可以在循环主体中的任何位置添加continue,而不会造成循环破坏。

PS:实际上,我更喜欢其他答案,但我将其保留为零,因为这是最小的更改,并且如果可能,应避免回避增量/检查循环体内的循环计数器(并且可以在此处进行) )。