Как равенство итератора STL устанавливается?

Если вы хотите более краткое решение, используя maplist/2, вы можете сделать что-то вроде:

isTwo(2) :- write('Yes'), !.
isTwo(_):- write('No').

test(L):-
    maplist(isTwo,L).

?- test([1,3,3,2,2,7,2,9]).
NoNoNoYesYesNoYesNo
true

test/1 не является обязательным, я добавил его только для ясности ...

11
задан Daniel 10 May 2009 в 05:32
поделиться

4 ответа

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

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

12
ответ дан 3 December 2019 в 06:47
поделиться

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

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

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

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

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

Вы вызываете Undefined Behavior.

Что делать, если я сравниваю допустимое значение с тем, которое находится вне диапазона? Это всегда ложь?

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

2
ответ дан 3 December 2019 в 06:47
поделиться

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

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

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

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

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

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

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

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

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

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

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

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

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

1
ответ дан 3 December 2019 в 06:47
поделиться

Дэниел спросил: Мне было интересно, как устанавливается равенство (==) для итераторов 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 [twoirectional.iterators], 24.2.5 [random.access.iterators]) , который использует два значения итератора в качестве аргументов (сноска) , которые были получены из двух разных диапазонов r1 и r2 (включая их прошедшие - конечные значения), которые не являются поддиапазонами одного общего диапазона , не определено , ^_^

Daniel asked: What about if I compare a valid value with one that's out of range? Is that always false?

Same as above.

3
ответ дан 3 December 2019 в 06:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: