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

Const для сравнения без итератора, если они действительны

У меня есть два итератора в контейнер, один const и один не const. Есть ли проблема с их сопоставлением, чтобы убедиться, что оба они относятся к одному и тому же объекту в контейнере? Это общий вопрос итератора С++ 11:

Можно ли закончить сопоставление итератора const и non-const, чтобы убедиться, что они оба относятся к одному и тому же объекту, независимо от типа контейнер (то есть они оба являются итераторами, которые, как гарантируют, будут ссылаться к объектам в одном контейнере или конце контейнера(), но один из них const, а другой нет)?

Например, рассмотрим следующий код:

some_c++11_container container;

// Populate container
...

some_c++11_container::iterator iObject1=container.begin();
some_c++11_container::const_iterator ciObject2=container.cbegin();

// Some operations that move iObject1 and ciObject2 around the container
...

if (ciObject2==iObject1) // Is this comparison allowed by the C++11 standard?
  ...; //Perform some action contingent on the equality of the two iterators
4b9b3361

Ответ 1

Да, это будет работать так, как вы ожидаете.

Стандарт гарантирует, что для любого типа контейнера some_container::iterator может быть неявно преобразован в some_container::const_iterator.

Первая таблица в 23.2.1 [container.requirements.general] после определения X как типа контейнера, которая содержит объекты типа T, имеет:

Выражение: X::iterator

Тип возврата: тип итератора, тип значения которого T

Примечание: любая категория итераторов, соответствующая требованиям прямого итератора. конвертируется в X::const_iterator.


Выражение: X::const_iterator

Тип возврата: константный тип итератора, тип значения которого T

Примечание: любая категория итераторов, соответствующая требованиям прямого итератора.

(Это не выражения, а типы, а не "возвращаемые типы", но то, как они сжаты в таблицу, которая в основном выражает.)

Итак, когда у вас есть ciObject2==iObject1, компилятор замечает, что лучшим operator== является ciObject2==some_container::const_iterator(iObject1). И operator== на двух const_iterator сообщает вам, ссылаются ли они на один и тот же элемент.

(Я ничего не вижу, явно говоря, что результат этого преобразования относится к тому же объекту, что и исходный iterator. Я думаю, это только что понято.)

Ответ 2

Я не думаю, что это может быть проблема, сравнивающая их. Если у вас есть константный итератор, когда вы проверяете, что это конец, то итератор end() возвращает не const.

Ответ 3

IIRC iterator неявно преобразуется в const_iterator. И результат должен указывать на ту же позицию.

Если так, смешанное сравнение выполнит преобразование, сравните совместимые совместимые константы.

Ответ 4

Из §24.2.3/1

Класс или тип указателя X удовлетворяет требованиям входного итератора для типа значения T, если X удовлетворяет требованиям Iterator (24.2.2) и EqualityComparable (Таблица 17)..

Таким образом, итераторы ввода должны быть EqualityComparable.

Все итераторы контейнеров стандартной библиотеки должны удовлетворять требованиям итератора в прямом направлении (§23.2.1 - таблица 96). Поскольку эти требования являются надмножеством требований к входному итератору, следует, что эти итераторы должны удовлетворять концепции EqualityComparable.

Кроме того, из §23.2.1 - Таблица 96, X::iterator требуется преобразовать в X::const_iterator.

Добавление этих двух ответов отвечает на ваш вопрос о том, что стандарт действительно соответствует стандарту, который сравнивает Container::const_iterator с a Container::iterator (если оба являются действительными итераторами, указывающими на один и тот же контейнер).