Search code examples
c++listreverse-iterator

C++ iterate container backwards N steps


In C++ I can use reverse_iterator to loop elements of container, say, list, backwards.

How do I iterate over a certain number of elements? Not reaching the beginning? This code works, but I feel there is a better way.

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;
}

Expected output {5, 4, 3}.


Solution

  • You can adjust the loop as follows:

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

    but note that for this to work reliably, you need to check that the list is at least of size 3 or adjust the parameter to std::next as in const auto n = std::min<std::size_t>(3, mylist.size());.

    With C++20, you should be able to go with (obviously not tested)

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

    This renders the size testing superfluous, as take_view is bound by the range size (it performs this check internally).