C++11 Range-based for loop for std::list

  • A+

If I understand the range-based for loop correctly, which expands

for ( range_declaration : range_expression ) loop_statement 


{     auto && __range = range_expression ;     for (auto __begin = begin_expr, __end = end_expr;             __begin != __end; ++__begin) {         range_declaration = *__begin;         loop_statement     } } 

thus incrementing the pointer, and if I understand that std::lists are internally implemented as doubly linked lists, isn't it correct to assume that something like this would not print 0 1 2 3, since the memory addresses are not sequential (implied by the ++__begin)?

std::list<int> myList = {0, 1}; std::list<int> otherList = {10, 11}; myList.push_back(2); myList.push_back(3);  for(auto& i: myList)     std::cout << i << " "; 

And yet it does print correctly. So then, is std::list::iterator overriding the behavior of the operators used in the range-for-loop expansion?

This is of particular importance to me if I choose to implement my own range-for iterable data structures.


Yes, iterators generally overload ++, *, ->, ==, != and sometimes + integral and -- and - integral and < etc, depending on "iterator category".

std::list::iterator is a bidirectional iterator, so overrides the first set of operators and only -- from the second.

Iterators are not pointers. On the other hand, pointers are both iterators, and the model upon which iterators where based.

Iterators that are fundamentally pointers are iterators into random access containers that store their data contiguously; vector, string, array and initializer_list.

Most of those still aren't raw pointers, but rather wrappers around the pointer. This both permits some additional type safety and allows debug builds to do bounds checking and similar other checks.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: