1

Suppose we have a vector of vectors and we initialize all elements to 0.

vector<vector<int>> P(MyObjects.size() + 1, vector<int>(MyBag.MaxCapacity + 1, 0));

My question is:

Is it possible to iterate over a vector starting from 1 column and 1 changing in someway following code?

for (auto& row : P) //Tried to add (row + 1) : P but I'm receiving an Error
  {
    for (auto& elem : row) //Tried to add(elem + 1) : row but I'm receiving an Error
    {
       std::cout << elem << "  ";
    }
  }

I was looking for the answer here on SO and on Web but there was nothing even similiar to it.

I'm only interested in solutions which use auto

EDIT: Here is the output of Errors

main.cpp:74:18: error: expected ‘;’ before ‘+’ token
   for (auto& row +1 : P)
                  ^
main.cpp:74:21: error: expected ‘;’ before ‘:’ token
   for (auto& row +1 : P)
                     ^
main.cpp:74:21: error: expected primary-expression before ‘:’ token
main.cpp:74:21: error: expected ‘)’ before ‘:’ token
main.cpp:74:21: error: expected primary-expression before ‘:’ token

And there is a Code which I was trying to use

for (auto& row + 1 : P)
  {
    for (auto& elem + 1 : row)
    {
     std::cout << elem << "  ";
    }
  }

Yes I know that we can use the following syntax

for(vector< vector<int> >::iterator row = v.begin() + 1; row != v.end(); ++row) {
    for(vector<int>::iterator col = row->begin() + 1; col != row->end(); ++col) {
        cout << *col;
    }
}

but I do not want to use it.

Barry
  • 286,269
  • 29
  • 621
  • 977
FieryCod
  • 1,674
  • 1
  • 19
  • 27
  • 1
    _"Is it possible to iterate over an vector starting from 1 column and 1 changing in someway following code?"_ Sure, it is. You are probably asking the wrong question. Provide a [MCVE] and show your error messages verbatim. – πάντα ῥεῖ Apr 24 '16 at 17:48
  • 1
    _"I'm only interested in solutions which use auto"_ That's a bit like asking: _I have to drill out a screw from my wall. What's the right tool to do so? Note I'm only interested in solutions using a hammer (because that's the only tool I have at hand)_. – πάντα ῥεῖ Apr 24 '16 at 17:51
  • You cannot have an lvalue as an expression. – ayushgp Apr 24 '16 at 17:52
  • @Charlie You are obviously confusing `auto&` with something like `std::vector::iterator`. – πάντα ῥεῖ Apr 24 '16 at 17:53
  • You are not correct, I asked this question, because other people may have a benefit from it not only me. – FieryCod Apr 24 '16 at 17:53
  • @Charllie Well, what should we do? Setting up a canonical question? See what I've collected about that topic within the last 5 hours: [Deleting/Removing a rectangle from a vector C++ (SDL2)](http://stackoverflow.com/questions/36826458/deleting-removing-a-rectangle-from-a-vector-c-sdl2), [C++ Erasing from list of pairs](http://stackoverflow.com/questions/36823150/c-erasing-from-list-of-pairs). – πάντα ῥεῖ Apr 24 '16 at 17:56
  • 1
    You don't want `for(vector< vector >::iterator row = v.begin() + 1; row != v.end(); ++row)`, but what about `for(auto row = v.begin() + 1; row != v.end(); ++row)`? – kfsone Apr 24 '16 at 18:17
  • Why you are so revengeful and why did you downvoted my question? – FieryCod Apr 24 '16 at 18:18
  • @kfsone Well I do not know why I didn't come up with it. Yea you got right.You can add your comment as an answer ;) – FieryCod Apr 24 '16 at 18:20

1 Answers1

4

The expression on the right side of the colon here:

for (auto& row : P) { ... }
                ^^^

has to be a container in the C++ sense. Something that you can call begin() and end() on that yields two iterators of the same (for now) type, where that iterator is incrementable, comparable, and dereferenceable.

If what you want to do is skip the first element in the container, you'll need to create a new view of P that simply offsets the first iterator by one. What you're modifying is the container you're iterating over, not the values. So we want something like:

for (auto& row : offset(P, 1)) { ... }

offset takes a container and an offset that it'll apply to P's begin iterator:

template <class C>
iter_pair<iterator_t<C&>> offset(C& container, size_t skip) {
    return {std::next(container.begin(), skip), container.end()};
}

Where iter_pair is very straightforward:

template <class It>
struct iter_pair {
    It b, e;

    It begin() const { return b; }
    It end() const { return e; }
};

And iterator_t is buckets of fun. This is a simplified version:

template <class C>
using iterator_t = decltype(std::begin(std::declval<C>()));

Demo

Barry
  • 286,269
  • 29
  • 621
  • 977