Beginner's Guide

# IteratorsIteratorsIterators

• objects that point to a location
• used to iterate over container elements in a data-layout-agnostic way
• also used to specify positions and ranges in containers (for insertion, deletion, etc.)

In the following chapters the notation `@name` will be used to denote an iterator object / parameter / return value.

## Default IteratorsDefault

##### Obtainable from standard containers

either with member functions:

• ```container.begin() ```@first_element
• ```container.end() ```@one_behind_last_element

or with free-standing functions:

• ```std::begin(container) ```@first_element
• ```std::end(container) ```@one_behind_last_element
``````vector<int> v {1,2,3,4,5,6,7}
auto i = begin(v);
auto e = end(v);``````
``````1234567

i      e``````
``````cout << *i;
cout << *(i+2);
cout << *e;``````
``````prints 1
prints 3
UNDEFINED BEHAVIOR``````

The `end` iterator is only intended to be used as position indicator, it must not be used to access an element.

``````++i;

cout << *i;
i += 2;

cout << *i;
--i;

cout << *i;
i += 5;
if(i == end(v))
cout << "at end";``````
``````1234567

prints 2
1234567

prints 4
1234567

prints 3
1234567

at end``````
##### Iterator-Based Loop
``````std::vector<int> v {1, 2, 3, 4, 5, 6};
for(auto i = begin(v); i != end(v); ++i) {   cout << *i; }``````

## Reverse IteratorsReverse

##### Obtainable from (many, but not all) standard containers

either with member functions:

• ```container.rbegin() ```@last_element
• ```container.rend() ```@one_before_first_element

or with free-standing functions:

• ```std::rbegin(container) ```@last_element
• ```std::rend(container) ```@one_before_first_element
``````vector<int> v {1,2,3,4,5,6,7}
auto i = rbegin(v);
auto e = rend(v);``````
`````` 1234567

e      i``````
``````cout << *i;
cout << *(i+2);
cout << *e;``````
``````prints 7
prints 5
UNDEFINED BEHAVIOR``````

The `rend` iterator is only intended to be used as position indicator, it must not be used to access an element.

``````++i;

cout << *i;
i += 2;

cout << *i;
--i;

cout << *i;
i += 5;
if(i == rend(v))
cout << "at rend";``````
`````` 1234567

prints 6
1234567

prints 4
1234567

prints 5
1234567

at rend``````
##### Reverse Iterator-Based Loop
``````std::vector<int> v {1, 2, 3, 4, 5, 6};
for(auto i = rbegin(v); i != rend(v); ++i) {   cout << *i; }``````
• reverse position = normal position - 1
• normal position = reverse position + 1
``````vector<int> v {1,2,3};
auto re = rbegin(v);
auto fw = re.base();``````
``````re
123
fw ``````

``````void swap_adjacent_pairs(std::vector<int>& v) {
if(v.size() < 2) return;
for(auto i=begin(v), j=i+1, e=end(v);      j < e; i+=2, j+=2)   {
swap(*i,*j);
}
}``````
``````vector<int> w {1,2,3,4,5,6};
``````123456
214365``````

## Iterator RangesRanges end-of-range iterator `q` points one behind the last element in the range • to be erased from a container

• to be inserted into a container
• to be assigned to a container
• to be processed by a standard algorithm 