6

Consider the following code example :

#include<iostream>
#include<vector>
#include<typeinfo>

int main(){
    std::vector<int> v = {1 ,2,4};
    for(auto &i:v)  std::cout<<typeid(i).name();
    for(auto k = v.begin(); k!=v.end();++k) std::cout<<typeid(k).name();
    return 0;
}

The first loop represents range based for-loops , and second one are regular for loops with iterators. I have used regular ones a lot , and from my experience , auto k is of type of iterator , while range based loops had type of auto i as int. Output of above program is:

i & N9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE

Is this normal behavior for range based for loops over collections like vectors ( somewhere mentioned) ? Because someone (like me) would assume range based for loops are just shorthand for regular for loops.

Abhinav Gauniyal
  • 6,285
  • 6
  • 44
  • 90
  • 1
    This is as designed. The range based `for` loop gives you the elements. Is that a good enough answer? – Magnus Hoff Apr 11 '15 at 13:13
  • 1
    There must be a reason for them to be designed as such , which I fail to see. Are there any references to it? – Abhinav Gauniyal Apr 11 '15 at 13:15
  • Note that the two loops are not entirely equivalent: Your explicit range-based loop evaluates `end()` in every turn and therefore can adapt to structural changes of the vector (as long as they don't invalidate `k`). The range-based loop evaluates `end()` only at the beginning and therefore you better leave the vector's structure alone inside. Therefore it makes sense that you're not provided with the means to change that structure (i.e. iterators), but only with the means to access/change the values. – celtschk Apr 11 '15 at 13:28
  • @celtschk thanks for that great insight :) . I certainly didn't knew that. – Abhinav Gauniyal Apr 11 '15 at 13:33
  • "Are there any references to it" - this will be documented in the C++ standard. – Oliver Charlesworth Apr 11 '15 at 13:41
  • 1
    typeid::name return value is implementation-defined. http://stackoverflow.com/questions/4465872/why-typeid-name-returns-weird-characters-using-gcc – Eric Pruneau Apr 11 '15 at 14:26

2 Answers2

10

The answer is what Magnus already stated: Yes, it is a normal behavior. Range loops are for cases when we are interested in examining every item in a collection (unless we break out sooner) and aren't interested in doing anything with the container itself. Like it was already stated, range loops are optimized that way, e.g. it indeed computes the finishing condition only once. In my opinion, this is a very nice and welcome addition to the variety of loop options in c++, since we do often face this very exact situation: we get a container and are interested in simply going through them one by one in either const or non-const fashion.

Arnošt Löbel
  • 116
  • 1
  • 2
-1

range based for loop will give container element.

exa:

vectorv{5,7,10};

for(auto i:v)

cout<<i ; //5,7,10

Ramanand Yadav
  • 165
  • 1
  • 3