Why does std::array::begin not return an iterator?

Viewed 278

I am trying to build a nested iterator template and relied on iterators having various traits like value_type. But as it turns out, not all STL types even return iterators with those traits. For instance:

#include <array>
#include <type_traits>

template <typename T>
using iterator_t = decltype(std::declval<T>().begin());

static_assert(std::is_same_v<iterator_t<std::array<int, 3>>, int*>);

This code compiles and shows that the actual type of the array iterator is int*. In that case, how can I still access traits such as value_type etc?

2 Answers

The standard doesn't specify how the iterator should be implemented and what the exact type it should be. In fact pointers like int* does satisfy the requirements of the iterator of std::array, so it's quite legitimate for implementation.

You can use std::iterator_traits to get the value_type as std::iterator_traits<iterator_t<std::array<int, 3>>>::value_type, it works with pointers too.

int* is an iterator as it satisfies all the requirements necessary of an iterator.

Informally:

  1. You can deference it (unless it's past the final element of the array).

  2. You can increment it (as it's a pointer in an array).

  3. You can copy int* to another int*.

  4. You can call std::swap with int* as the types.

Related