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
Ответы
Ответ 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
(если оба являются действительными итераторами, указывающими на один и тот же контейнер).