Являются ли прямые-итераторы выходными-итераторами?

Должны ли ForwardIterators быть OutputIterators? Моя текущая STL-реализация (VS2012) выводится forward_iterator_tag от обоих input_iterator_tag а также output_iterator_tag, но я не могу найти это требование в стандарте [N3485].

8

Решение

В C ++ 11 нет, прямые итераторы не обязаны быть выходными итераторами. Выходные требования к итератору подобны дополнительному набору требований, которые может иметь итератор, независимо от остальных требований итератора, которым он соответствует. Прямые итераторы должны быть только входными итераторами (§24.2.5 / 1):

Класс X или указатель типа X удовлетворяет требованиям прямого итератора, если:

  • X удовлетворяет требованиям входного итератора

Фактически, прямой итератор удовлетворяет требованиям выходного итератора, только если он является изменяемым итератором для последовательности типов, назначаемых для копирования..

† или постоянный итератор для последовательности типов с operator=(...) const определяется с изменяемыми членами.

Более конкретно, теги итератора определяются конкретно стандартом как (§24.4.3 / 2):

namespace std {
struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag { };
struct random_access_iterator_tag: public bidirectional_iterator_tag { };
}

Как вы видете, forward_iterator_tag должно наследоваться только от input_iterator_tag,


В C ++ 03 указано, что прямые итераторы удовлетворяют требованиям итераторов ввода и вывода:

Прямые итераторы удовлетворяют всем требованиям итераторов ввода и вывода и могут использоваться всякий раз, когда указывается любой вид.

Но это затем противоречит следующему абзацу, утверждая, что постоянный прямой итератор не удовлетворяет требованиям для выходных итераторов:

Помимо своей категории, итератор прямого, двунаправленного или произвольного доступа также может быть изменяемым или постоянным в зависимости от того, действует ли результат выражения * i как ссылка или как ссылка на константу. Постоянные итераторы не удовлетворяют требованиям для выходных итераторов, и результат выражения * i (для постоянного итератора i) нельзя использовать в выражении, где требуется lvalue.

Однако определение тегов итератора такое же, как и в C ++ 11. Был отчет о дефектах для этой противоречивой формулировки, но она была закрыта как Не Дефект, потому что первая цитата находится во «вводном тексте» раздела и, вероятно, будет переписана в будущем (как это было).


Определение SGI прямого итератора дается как уточнение итераторов ввода и вывода (благодаря @BenVoigt в комментариях).

Тем не менее, если мы посмотрим на реализация тегов итератора, мы находим, что forward_iterator_tag все еще наследует только от input_iterator_tag,

Похоже, это было областью путаницы в прошлом, но если VS2012 определяет forward_iterator_tag как наследование от обоих output_— а также input_iterator_tagЯ могу только предположить, что это ошибка.

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]