12

I want to iterate through some std::vectors in a for loop but depending on some conditions, the vectors shall be iterated either forward or backward. I thought, I could easily do it by using either normal iterators or reverse iterators like this:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec{0, 1, 2, 3, 5, 6, 7};
    bool reverse = true;
    std::iterator<random_access_iterator_tag, int> it, end_it;

    if (reverse) {
      it = vec.rbegin();
      end_it = vec.rend();
    } else {
      it = vec.begin();
      end_it = vec.end();
    }

    for (; it != end_it; it++) {
        cout << *it << ", ";
    }
    return 0;
}

But unfortunately vector::begin() and vector::rbegin() don't seem to be using the same parent class. Is there another way to do what I want without having two different loops in an if-else-structure? Of course I could create a function/lambda for the loop body or use some index arithmetic but is there a more elegant way?

The compiler complains about the assignment it = vec.begin() as they are different types. gcc and VC++ output different errors and seem to use different types for the return values of vector::begin.

Sven Hoek
  • 170
  • 9
  • See https://stackoverflow.com/questions/2037867/can-i-convert-a-reverse-iterator-to-a-forward-iterator – Captain Giraffe Jul 26 '18 at 18:11
  • 1
    I don't think it is a dupe. The linked question is about conversion from reverse iterator to iterator, this question - about uniform way to traverse the container. – Edgar Rokjān Jul 26 '18 at 18:17
  • @Sven okay, cool. So what do you mean by it doesn't seem to use the same parent class? What's the error you're getting that makes you say that? – CodeMonkey Jul 26 '18 at 18:55
  • 1
    As suggested/pondered in the question, I'd use a template lambda like `[](auto it, auto end_it) { for(; it != end_it; ++it) cout << *it << ", ";`. – Eljay Jul 26 '18 at 18:59
  • @CodeMonkey I edited my question a bit. I switched to repl.it as a small testing environment and now I see that VC and gcc have different errors but both because of incompatible types. – Sven Hoek Jul 26 '18 at 19:24

1 Answers1

-2

Not sure if better and you will accept solution without std::iterator, but I consider this slightly more elegant:

#include <iostream>
#include <vector>

using namespace std;

int main() {
vector<int> vec{0, 1, 2, 3, 4, 5, 6};
bool reverse = true;

for(int i: vec){
    if(reverse) 
        cout << vec[vec.size()-i] << endl;
    else 
        cout << vec[i] << endl;
  }
}

Not very efficient tho, as you have to check if in every loop.

PStarczewski
  • 479
  • 2
  • 17
  • This is not what I'm trying to do. The numbers in the vectors are just an example and not supposed to be used as index (btw, number 4 is missing in mine). The traversing in different directions is what I want. – Sven Hoek Jul 26 '18 at 18:55