Как устанавливается равенство итераторов STL? - PullRequest
11 голосов
/ 10 мая 2009

Мне было интересно, как устанавливается равенство (==) для итераторов STL? Это простое сравнение указателей (и, следовательно, основанное на адресах) или что-то более причудливое?

Если у меня есть два итератора из двух разных объектов списка, и я сравниваю их, будет ли результат всегда ложным?

Как насчет того, чтобы сравнить действительное значение с тем, которое выходит за пределы допустимого диапазона? Это всегда ложно?

Ответы [ 4 ]

12 голосов
/ 10 мая 2009

Классы итераторов могут определять перегруженные операторы ==, если они этого хотят. Так что результат зависит от реализации operator==.

Вы не должны сравнивать итераторы из разных контейнеров. Я думаю, что некоторые реализации отладки STL будут выдавать предупреждение, если вы сделаете это, что поможет вам обнаружить случаи такого ошибочного использования в вашем коде.

3 голосов
/ 19 октября 2009

Даниил спросил: Мне было интересно, как устанавливается равенство (==) для итераторов STL? Это простое сравнение указателей (и, следовательно, основанное на адресах) или что-то более причудливое?

Это зависит от реализации. Прямо сейчас в Visual C ++ 2008 я вижу следующий код (для итератора списка):

bool operator==(const _Myt_iter& _Right) const
{   // test for iterator equality

#if _HAS_ITERATOR_DEBUGGING
    _Compat(_Right);
#else
    _SCL_SECURE_TRAITS_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
#endif /* _HAS_ITERATOR_DEBUGGING */

    return (_Ptr == _Right._Ptr);
}

Вы увидите выше, что есть и код для проверки правильности итератора, и _Ptr, являющийся указателем на узел списка.

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

Даниил спросил: Если у меня есть два итератора из двух разных объектов списка, и я сравниваю их, будет ли результат всегда ложным?

До сих пор кажется, что стандарт был несколько неясен по этому вопросу. Видимо, они явно напишут, что операция такого типа имеет неопределенные результаты:

Цитирование: http://www.open -std.org / jtc1 / sc22 / wg21 / docs / lwg-active.html # 446

Результат использования любой операции итератора (24.2.1 [input.iterators], 24.2.2 [output.iterators], 24.2.3 [forward.iterators], 24.2.4 [двунаправленный. итераторы], 24.2.5 [random.access.iterators]) , который использует два значения итератора в качестве аргументов (сноска) , которые были получены из двух разных диапазонов r1 и r2 (включая их прошлое конечные значения), которые не являются поддиапазонами одного общего диапазона , не определено , если явно не указано иное.

сноска) Среди других этих операций: ==, <, двоичное - и копирование </p>

Так что я думаю, что сравнивать итератор из разных контейнеров - это зло ^ _ ^

Даниил спросил: Как насчет того, чтобы сравнить действительное значение с тем, которое выходит за пределы допустимого диапазона? Это всегда ложно?

То же, что и выше.

2 голосов
/ 10 мая 2009

Мне было интересно, как устанавливается равенство (==) для итераторов STL?

Не все итераторы можно сравнивать (например, выходные итераторы не обязаны предоставлять op==). Вы можете использовать operator==, когда концепция диапазона четко определена для рассматриваемой категории итераторов.

Это простое сравнение указателей (и, следовательно, основанное на адресах) или что-то более причудливое?

Итераторы всегда реализуются с помощью указателей. Редактировать: я говорю реализовано с - что относится не к стандартному требованию, а к практике использования poitners в качестве базовой конструкции Реализации (например, VS) могут иметь специальные проверочные проверки, вставленные хотя.

Если у меня есть два итератора из двух разных объектов списка, и я сравниваю их, будет ли результат всегда ложным?

Вы вызываете неопределенное поведение.

Как насчет того, чтобы сравнить действительное значение с недопустимым? Это всегда ложно?

Опять же, вы будете вызывать UB. Единственное допустимое сравнение - между двумя итераторами в одном и том же диапазоне или между одним в диапазоне и другим с последним последним элементом. Обратите внимание, что вы можете сравнивать только итератор с последним последним элементом, разыменовывая те же выводы, что и UB.

1 голос
/ 10 мая 2009

Тест на равенство зависит от типа итератора, который вы используете, или может не существовать вообще. Если вы действительно хотите знать, вы всегда можете проверить исходный код реализации STL, которую вы используете, ищите operator == () в классе итераторов.

Итераторы НЕ всегда являются указателями, и, действительно, в некоторых «безопасных» версиях STL никогда не являются указателями. Итераторы для векторов и строк обычно реализуются как указатели, потому что они могут быть. Итераторы для запросов, списков, множеств и карт не могут быть указателями в какой-либо полуэффективной реализации.

Что такое итераторы, это тип умного указателя. Они следуют общему принципу: если они выглядят и ведут себя как указатель, то они являются указателем для пользователя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...