Почему для концепции output_iterator не требуется output_iterator_tag? - PullRequest
6 голосов
/ 11 июля 2020

C ++ 20 представляет правильные концепции для различных типов итераторов в стандартной библиотеке (ввод, вывод, пересылка, двунаправленный, произвольный доступ, ...).

Хотя исходные именованные требования для них В типах теги итератора из std::iterator_traits вообще не упоминаются, новые концепции C ++ 20 явно требуют их. См., Например, концепцию input_iterator ( [iterator.concept.input] ):

template<class I>
  concept input_iterator =
    input_or_output_iterator<I> &&
    indirectly_readable<I> &&
    requires { typename ITER_CONCEPT(I); } &&
    derived_from<ITER_CONCEPT(I), input_iterator_tag>;

Обратите внимание на проверку тега итератора в последней строке. Все концепции итератора проверяют соответствующий тег, например, , за исключением итератора вывода . Итератор вывода всегда был особенным в этом отношении, с первых дней существования Ranges TS :

В отличие от требований итератора вывода в стандарте C ++, OutputIterator в Ranges TS выполняет не требует определения тега категории итератора.

В чем причина такой особой обработки итераторов вывода?

1 Ответ

3 голосов
/ 12 июля 2020

В C ++ 20 категории итераторов обычно определяются автоматически на основе синтаксиса. Явное использование тегов итератора используется только для отказа или включения:

  • все, что слабее, чем random_access_iterator_tag, используется для отказа от более сильной категории итератора (например, итератор ввода может быть синтаксически неотличим от прямого итератора);
  • contiguous_iterator_tag используется для выбора contiguous_iterator, поскольку смежность является относительно редким свойством, которое также не может быть обнаружено синтаксически.

Итераторы вывода не нуждаются в таком мелкомасштабном элементе управления - вы можете или не можете писать в него, и это определяется синтаксически.

Что касается предоставления подписки / отказа, объяснил Кейси Картер :

  • Передача аргумента библиотечному компоненту, который ограничивает этот аргумент является неявным утверждением, что аргумент либо не удовлетворяет ограничению (не соответствует требованиям syntacti c), либо моделирует ограничение (соответствует синтаксису и семантическим требованиям), поэтому opt-in / opt -out обычно не требуется.

  • Возможности opt-in / opt-out предоставляются только тогда, когда мы хотим, чтобы библиотека предполагала, что аргумент, моделирующий некую концепцию X, дополнительно моделирует некоторые уточнение Y для X, когда оно удовлетворяет Y (я называл это «продвижение semanti c», но это не устоявшийся термин). Выбор согласия или отказа зависит от ожидаемой частоты ложных срабатываний.

«Semanti c продвижение» часто выполняется для невыводимых аргументов итератора. Итераторам вывода нечего повышать.

...