c++templatesiteratorc++17stdarray

Why does std::array::begin return a pointer instead of an iterator?


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?


Solution

  • The standard doesn't specify how the iterator should be implemented and what the exact type it should be. It just says that std::array is a ContiguousContainer, meaning that its iterator is ContiguousIterator.

    In fact, pointers like int* do 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, like:

    std::iterator_traits<std::iterator_t<std::array<int, 3>>>::value_type
    

    It works with pointers too.