WedX - журнал о программировании и компьютерных науках

сравнения константных и неконстантных итераторов, действительны ли они [дубликаты]

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

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

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

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
03.06.2013

  • Конечно, это действительно. Но обратите внимание, что вы сравниваете итераторы, а не значение, указанное итераторами. 03.06.2013
  • @ user814628 Доказательства, пожалуйста? 03.06.2013
  • Я думал, что это очевидно. Если мы можем сравнить неконстантный объект с константным, нет никаких причин, по которым мы не можем проводить сравнения итераторов. 03.06.2013
  • some_container::iterator и some_container::const_iterator могут быть разными типами. Хотя они моделируют T * и T const *, это не то, чем они являются на самом деле. Вот почему это хороший вопрос. Вам будет трудно найти пример, который не работает, но это не значит, что Стандарт гарантирует, что он будет работать. Ну, за исключением того, что теперь пара ответов показывает, что это так, но это не то, что я бы посчитал очевидным/тривиальным. 03.06.2013
  • Знаете ли вы, что оба итератора ссылаются на элементы в одном и том же контейнере? Это не сразу ясно из вопроса, поскольку вы исключили инициализацию в своем примере. 04.06.2013
  • @ Адриан, я обновил пример, чтобы прояснить этот момент. 04.06.2013

Ответы:


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. Я думаю, это только что поняли.)

03.06.2013
  • Если вы можете процитировать главу и стих, я сочту вопрос решенным и поставлю вам галочку. 03.06.2013
  • Обратите внимание, что это не требование к контейнерам, а спецификация интерфейса для контейнеров, определенных в стандарте. Таким образом, это не относится ко всем итераторам, а только к итераторам из стандартных контейнеров. Другие источники итераторов (контейнеры и т. д.) см. в документации. 03.06.2013

  • 2

    Из §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 с Container::iterator было четко определенным (при условии, что оба являются допустимыми итераторами, указывающими на один и тот же контейнер).

    03.06.2013

    3

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

    03.06.2013
  • Я заметил, что возврат end() является конечным возвращаемым типом, будет ли автоматическое сохранение const 03.06.2013
  • Функции-члены Container::end() имеют 2 перегрузки: одна возвращает итератор const, а другая не const. 03.06.2013
  • Я всегда думал, что cbegin() и cend() были добавлены, чтобы помочь с автоматическим выводом типа. Например: auto ciObject=myContainer.cbegin(); // ciObject is a const iterator to object 03.06.2013

  • 4

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

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

    03.06.2013
    Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: wedx@cp9.ru