Почему std :: array :: begin не возвращает итератор? - PullRequest
5 голосов
/ 26 мая 2020

Я пытаюсь создать шаблон вложенного итератора и полагаюсь на итераторы, имеющие различные характеристики, например value_type. Но, как оказалось, не все типы STL даже возвращают итераторы с этими характеристиками. Например:

#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*>);

Этот код компилируется и показывает, что фактический тип итератора массива - int*. В таком случае, как я могу получить доступ к таким чертам, как value_type et c?

Ответы [ 2 ]

7 голосов
/ 26 мая 2020

Стандарт не определяет, как итератор должен быть реализован и какого именно типа он должен быть. Фактически, указатели, подобные int*, удовлетворяют требованиям итератора std::array, поэтому они вполне законны для реализации.

Вы можете использовать std::iterator_traits чтобы получить value_type как std::iterator_traits<iterator_t<std::array<int, 3>>>::value_type, он также работает с указателями.

5 голосов
/ 26 мая 2020

int* - это итератор, поскольку он удовлетворяет всем требованиям, необходимым для итератора.

Неформально:

  1. Вы можете deference it (если только он не прошел за последним элементом массива).

  2. Вы можете увеличить it (поскольку это указатель в массиве).

  3. Вы можете скопировать int* на другой int*.

  4. Вы можете позвонить std::swap с int* в качестве типов.

...