Skip to content

Instantly share code, notes, and snippets.

@milesrout
Last active August 29, 2015 14:18
Show Gist options
  • Save milesrout/29ee9158a4d2b1a6df99 to your computer and use it in GitHub Desktop.
Save milesrout/29ee9158a4d2b1a6df99 to your computer and use it in GitHub Desktop.
Understanding C++ Iterators

C++'s iterators are a generalisation of pointers-into-arrays. So you can write this:

void sort_array() {
    int arr[10] = {4, 5, 1, 7, 6, 3, 9, 2, 8, 0};
    std::sort(arr, arr + 10); // std::sort<int*>
}

just as you can write

void sort_vector() {
    std::vector<int> v = {4, 5, 1, 7, 6, 3, 9, 2, 8, 0};
    std::sort(v.begin(), v.end()); // std::sort<std::vector<int>::iterator>
}

And in general you can write

template <Container C, Integral T> // not-yet-legal concepts syntax
sort_container() {
    C<T> c = {4, 5, 1, 7, 8, 3, 9, 2, 8, 0};
    std::sort(std::begin(c), std::end(c));
}

Note: template <Container C, Integral T> means template <typename C, typename T> requires Container<C> && Integral<T>, which roughly means template <typename C, typename T, std::enable_if_t<std::is_integral_v<T> && std::is_container_v<C>>, if std::is_container existed

std::sort, because it is a function template, works for both T* (the sort of iterator you use into a T[N]) and std::vector<T>::iterator (the sort of iterator you use for a std::vector<T>, obviously). This only works because iterators are designed to mimic how pointers work.

And you can write these:

for (auto x : A) {
    std::cout << x << std::endl;
}

which are transformed into this (basically):

auto __end = std::end(A);    
for (auto __it = std::begin(A); __it != __end; ++__it) {
    std::cout << (*__it) << std::endl;
}

Which works whether A is arr or v.

Note: While in C you use T * everywhere, in modern C++ you use unique_ptr<T> for a owning-pointer-to-T, T * for a non-owning-nullable-pointer-toT, T& for a non-owning-non-nullable-pointer-to-T, std::array<T,N>::iterator for a pointer-into-std::array<T,N> (the replacement for T[N]) and std::vector<T>::iterator for a pointer-into-std::vector<T> (the replacement for T[]).

But iterators don't have to have the semantics of pointers, otherwise we'd just use pointers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment