Подтвердить что ты не робот

Непрерывное обнаружение итератора

С++ 17 представил концепцию ContiguousIterator http://en.cppreference.com/w/cpp/iterator. Однако не кажется, что есть планы contiguous_iterator_tag (так же, как мы теперь имеем random_access_iterator_tag), сообщенные std::iterator_traits<It>::iterator_category.

Почему contiguous_iterator_tag отсутствует?

Существует ли обычный протокол, чтобы определить, является ли итератор непрерывным? Или тест времени компиляции?

В прошлом я упомянул, что для контейнеров, если есть член .data(), который преобразуется в указатель на ::value, и существует элемент .size(), который может конвертироваться в различия указателя, следует предположить, что контейнер смежный, но я не могу вытащить аналогичную функцию итераторов.

Одним из решений может быть также функция data для непрерывных итераторов.

Конечно, концепция Contiguous работает, если &(it[n]) == (&(*it)) + n для всех n, но это невозможно проверить во время компиляции.


EDIT. Я нашел это видео, которое ставит его в более широкий контекст концепций С++. CppCon 2016: "Создание и расширение иерархии итераторов в современном многоярусном мире" Патриком Немцельским. Решение использует концепции (Lite), но в конце идея состоит в том, что непрерывные итераторы должны реализовывать функцию pointer_from (такую ​​же, как моя функция data(...)).

Вывод состоит в том, что концепции помогут формализовать теорию, но они не являются волшебными, в том смысле, что кто-то где-то определит новые специально названные функции над итераторами, которые смежны. Разговор обобщается на сегментированные итераторы (с соответствующими функциями segment и local), к сожалению, он ничего не говорит о перечеркнутых указателях.

4b9b3361

Ответ 1

Обоснование дано в N4284, который является принятой версией непрерывного предложения итераторов:

В этой статье термин "непрерывный итератор" вводится как уточнение итератора произвольного доступа без введения соответствующего contiguous_iterator_tag, который, как было установлено, нарушает код во время обсуждений в Issaquah статьи Невина Либера N3884 "Непрерывные итераторы: уточнение итераторов произвольного доступа",

Некоторый код был взломан, поскольку предполагал, что std::random_access_iterator не может быть уточнен, и имел явные проверки на это. По сути, он сломал плохой код, который не полагался на полиморфизм для проверки категорий итераторов, но тем не менее он нарушил код, поэтому contiguous_iterator_tag был удален из предложения.

Кроме того, возникла дополнительная проблема с классами std::reverse_iterator -like: обратный непрерывный итератор не может быть непрерывным итератором, но обычным итератором с произвольным доступом. Эту проблему можно было бы решить для std::reverse_iterator, но больше пользовательских оболочек итераторов, которые дополняют итератор при копировании его категории итераторов, либо лгали, либо перестали работать правильно (например, адаптеры Boost для итераторов).


Так как мой оригинальный ответ выше, std::contiguous_iterator_tag был возвращен в TS диапазона и будет присутствовать в С++ 20. Это позволяет избежать проблем, упомянутых выше, не предоставляя их через std::iterator_traits<T>::iterator_category но используя std::iterator_traits<T>::iterator_concept чтобы не нарушать любой существующий код.

Понятия ContiguousIterator и ContiguousRange. В настоящее время они в основном отличаются от своего аналога RandomAccess тем, что проверяют iterator_concept чтобы узнать, является ли он произвольным доступом или смежным итератором. Однако в другом предложении, Helpful pointers для ContiguousIterator также предлагается, чтобы смежные итераторы реализовали функцию to_address которая возвращает базовый указатель. Я не знаю, находится ли это предложение на рассмотрении, чтобы быть принятым или нет.