2

is there any reason why this works well

vector<CalcToken*>* myVec; //assume this contains CalcToken
for(vector<CalcToken *>::iterator it = myVec->begin() ; it != myVec->end() ; advance(it,1)) {
        cout<< (*it)->toString()<< " ";
    }

and this isnt getting me anything back?(advance(it,2))

for(vector<CalcToken *>::iterator it = myVec->begin() ; it != myVec->end() ; advance(it,2)) {
    cout<< (*it)->toString()<< " ";
}

i want to make a loop that should jump over some elements..., the following isnt working for me either it++,it++ and it+=2.

Etian Chamay
  • 185
  • 1
  • 1
  • 10
  • Did you try **it++? And "_the following isnt working for me_" why it is not working?? – Khalil Khalaf Jul 23 '16 at 17:27
  • Does it print out some elements and then garbage or does it not work at all? – bhuvy Jul 23 '16 at 17:27
  • @bhuvan-venkatesh the first one prints the elements well, the second one doesnt print at all. even if i print somthing outside the loop after that, it wont be printed. FirstStep , i dont know, it wont print anything when i use them. – Etian Chamay Jul 23 '16 at 17:29
  • Probably it's still in the buffer (cout is buffered) and the buffer doesn't get flushed before the undefined behaviour occurs. – celtschk Jul 24 '16 at 06:16

1 Answers1

2

If the vector has an odd number of elements, the advance call will try to advance the iterator past the end of the vector. This is undefined behaviour.

One way to fix it is to use the following modification of the standard advance (I'm limiting to forward direction to save myself work) [untested code]:

template<typename Iterator>
 void limited_advance(Iterator& it, Iterator end, unsigned distance,
                      std::random_access_iterator_tag)
{
  if ((end - it) < distance)
    it += distance;
  else
    it = end;
}

template<typename Iterator>
 void limited_advance(Iterator& it, Iterator end, unsigned distance,
                      ...)
{
  while (it != end && distance > 0)
  {
    ++it;
    --distance;
  }
}

template<typename Iterator>
 void limited_advance(Iterator& it, Iterator end, unsigned distance)
{
  limited_advance(it, end, distance,
                  typename std::iterator_traits<Iterator>::iterator_category());
}

and then replace advance(it,2) with limited_advance(it, myVec->end(), 2).

celtschk
  • 19,311
  • 3
  • 39
  • 64
  • Okay, this is better than my answer. I was trying to fixup the range check, but then realized that would lead to forming iterators to before-the-beginning of array and sort of checked-out. – Xarn Jul 23 '16 at 18:35