1

In Python, accessing an array's [-1]'th element gives the last element, and [-2] indexes the second to last element.

Is there a similar pretty syntax in C++ to access std::vector elements in reverse order?

becko
  • 15,722
  • 27
  • 80
  • 155

5 Answers5

8

Revese iterators:

for (auto it = v.rbegin(); it != v.rend(); ++it)
{

}

If you want to access to the i-th element from the end:

*(v.rbegin() + i)

Or if you don't want to look like a know-it-all:

*(v.end() - i - 1)

Note that in Python you will actually use v[-i-1] to get to the same element, so this one uses the same number.

The trick is that vector iterators are RandomAccessIterator so you can add and substract indices to them.

rodrigo
  • 86,825
  • 11
  • 134
  • 175
3

First, the other answers are great, and this one only complements them. Note that std::vector::reverse_iterator is a random access iterator. This means that you can use operator[] on it. In particular, the ith element starting from the last is v.rbegin()[i]. For convenience, you can define a variable auto rv = v.rbegin(); and then use rv[i] to access v[size-1-i].

Marc Glisse
  • 7,002
  • 2
  • 26
  • 51
0

You can use reverse iterators. Here you have a complete example on how to do it: .

But if you do not want to use a loop to traverse all the middle elements in the vector, you can also (along with reverse iterators) std::advance (it also traverses the vector as you would do it with a loop). Link to documentation.

You can also do it in the classical way: to access the last element you would do vector[vector.size()-1], to access the second element from the end vector[vector.size()-2]. I suppose you already knew it and were asking for a Python-look solution, but I do not know anything similar. Probably (but I am not sure) there is some way to overload the [] operator of the std::vector to allow what you are asking for. Here someone asked to do some changes in the way a vector operated: here.

Hope my answer was helpful.

Community
  • 1
  • 1
DanielFB
  • 23
  • 3
0

While @rodrigo's answer addresses the question well, I'd like to add one more point regarding looping through the std::vector.

In Python, looping through a list (or an iterable sequence in general) goes like:

mylist = [1, 2, 3, 4]

# from beginning to end
for elem in mylist:
    print(elem)

# from end to beginning
for elem in reversed(mylist):
    print(elem)

Since Python's for-loop is more akin to the "foreach" construct in other languages, the corresponding syntax in C++ actually uses the STL <algorithm>.

// header
#include <algorithm>

// example code
using namespace std;

vector<int> myvector {1, 2, 3, 4};

// forward
for_each(myvector.begin(), myvector.end(), [](int &elem){
    cout << elem << endl;
});

// reverse
for_each(myvector.rbegin(), myvector.rend(), [](int &elem){
    cout << elem << endl;
});

That last argument passed to std::for_each() is a lambda function which takes an int& as an argument.

nasser-sh
  • 3,493
  • 15
  • 27
0

Using Boost Range library:

#include <boost/range/adaptors.hpp>
#include <vector>
#include <iostream>

int main()
{
    std::vector<int> v {1,2,3,4,5};
    for (int i : v | boost::adaptors::reversed)
        std::cout << i << ' ';
}
jrok
  • 52,730
  • 9
  • 104
  • 139