сравнивая два итератора end () - PullRequest
3 голосов
/ 31 марта 2010
list<int> foo;
list<int> foo2;
list<int>::iterator foo_end = foo.end();
list<int>::iterator foo2_end = foo2.end();

for (list<int>::iterator it = foo.begin(); it != foo2_end; ++foo) <- notice != comparison here
{
   ...

это разрешено? будет ли он работать правильно.

Я склонен думать, что это зависит от реализации, кто-нибудь знает, говорит ли стандарт об этом что-нибудь?

Ответы [ 3 ]

7 голосов
/ 31 марта 2010

Об этом сообщалось о дефекте ( дефект LWG 446 ). В отчете о дефектах спрашивается, допустимо ли сравнивать итераторы, которые ссылаются на элементы разных контейнеров.

Примечания в отчете о дефектах объясняют, что это определенно предполагалось, что это не определено, но прямо не указано, что оно не определено.

Предложенное решение состояло в том, чтобы добавить в стандарт следующее, явно указав, что он не определен:

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

Редактировать: Этот язык не включен в C ++ 0x FCD. Эта проблема была фактически решена путем изменений в N3066 ; в частности, следующее дополнение (§24.2.5 / 2):

Область == для прямых итераторов - это область итераторов в одной и той же базовой последовательности.

2 голосов
/ 31 марта 2010

Да это разрешено (т.е. будет компилироваться).
Нет это не будет работать правильно.

foo2_end указывает на конец foo2, а не foo, поэтому ваш итератор начнется с начала foo и закончится, когда достигнет конца foo2, что никогда не произойдет, потому что Вы перебираете foo. Как только it повторяется после конца foo, вы получите ошибку сегмента.

Примечание: я предполагал, что вы хотели написать ++it, а не ++foo.

1 голос
/ 31 марта 2010

Компилируется, но в результате возникает ошибка сегмента. Итераторы являются объектно-зависимыми, и сравнение двух итераторов из разных объектов всегда приведет к неравенству. Таким образом, выражение it != foo2_end всегда будет иметь значение true, и ваша программа потерпит крах, когда it достигнет foo.end(), и вы попытаетесь разыменовать его.

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