STL: Сравнение валидных итераторов на разные контейнеры
От: Vain Россия google.ru
Дата: 06.11.10 15:05
Оценка: :)
Сравнение валидных итераторов на разные контейнеры одного типа как минимум в MSVC 2005 приводит к закрытию программы.
void main()
{
    std::list<int> a,b;

    std::list<int>::iterator i1 = a.end();
    std::list<int>::iterator i2 = b.end();

    if(i1 != i2) //Boom
    {
        printf("Just not equal\n");
    }
}

В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: derProgrammer Россия  
Дата: 06.11.10 15:30
Оценка:
V>Сравнение валидных итераторов на разные контейнеры одного типа как минимум в MSVC 2005 приводит к закрытию программы.
V>
V>void main()
V>{
V>    std::list<int> a,b;

V>    std::list<int>::iterator i1 = a.end();
V>    std::list<int>::iterator i2 = b.end();

V>    if(i1 != i2) //Boom
V>    {
V>        printf("Just not equal\n");
V>    }
V>}
V>

V>В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?

Можно унаследовать от std::list<T>::iterator собственный класс итераторов и работать с ними. Останется переопределить операторы сравнения, добавив проверку на несовпадение контейнеров итераторов. Хотя, конечно, реализация в таком случае будет зависеть от реализации STL (имени поля контейнера в protected секции итераторов), что не есть хорошо.
Re[2]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 15:59
Оценка:
Здравствуйте, derProgrammer, Вы писали:

V>>Сравнение валидных итераторов на разные контейнеры одного типа как минимум в MSVC 2005 приводит к закрытию программы.

V>>
V>>void main()
V>>{
V>>    std::list<int> a,b;

V>>    std::list<int>::iterator i1 = a.end();
V>>    std::list<int>::iterator i2 = b.end();

V>>    if(i1 != i2) //Boom
V>>    {
V>>        printf("Just not equal\n");
V>>    }
V>>}
V>>

V>>В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?
P>Можно унаследовать от std::list<T>::iterator собственный класс итераторов и работать с ними. Останется переопределить операторы сравнения, добавив проверку на несовпадение контейнеров итераторов. Хотя, конечно, реализация в таком случае будет зависеть от реализации STL (имени поля контейнера в protected секции итераторов), что не есть хорошо.
Это никуда не годится.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: Sni4ok  
Дата: 06.11.10 16:01
Оценка: 1 (1) +2
Здравствуйте, Vain, Вы писали:

V>Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?


никак, ненужно сравнивать итераторы от разных контейнеров.
Re[2]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 16:26
Оценка:
Здравствуйте, Sni4ok, Вы писали:

V>>Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?

S>никак, ненужно сравнивать итераторы от разных контейнеров.
В некоторых случаях, если хочешь избежать оверхеда — приходится сравнивать, иначе оверхед. По-крайней мере "сравнение указателей" не должно приводить к закрытию приложения, что щас и происходит.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: CreatorCray  
Дата: 06.11.10 16:56
Оценка:
Здравствуйте, Vain, Вы писали:

Может такой "хак" поможет:
if(&*i1 != &*i2)

не?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: STL: Сравнение валидных итераторов на разные контейне
От: Sni4ok  
Дата: 06.11.10 17:04
Оценка: :)
Здравствуйте, Vain, Вы писали:

V>По-крайней мере "сравнение указателей" не должно приводить к закрытию приложения, что щас и происходит.


Указатели это частный случай итераторов, и да их можно сравнивать, у стандартных контейнеров почти всегда итератор не является указателем(лишь в некоторых реализациях у вектора к примеру такое иногда бывает). Чтобы српавнивать итераторы(и то только на равенство, а скажем на больше меньше даже для random access iterator уже нельзя) из разных контейнеров вам очевидно нужно сравнивать и сами контейнеры, тоесть если нужна такая функциональность- реализуйте, на базе тогоже boost::iterator_facade'а это делается минут за несколько.
Re[4]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 17:15
Оценка: +1
Здравствуйте, Sni4ok, Вы писали:

V>>По-крайней мере "сравнение указателей" не должно приводить к закрытию приложения, что щас и происходит.

S>Указатели это частный случай итераторов, и да их можно сравнивать, у стандартных контейнеров почти всегда итератор не является указателем(лишь в некоторых реализациях у вектора к примеру такое иногда бывает). Чтобы српавнивать итераторы(и то только на равенство, а скажем на больше меньше даже для random access iterator уже нельзя) из разных контейнеров вам очевидно нужно сравнивать и сами контейнеры, тоесть если нужна такая функциональность- реализуйте, на базе тогоже boost::iterator_facade'а это делается минут за несколько.
А как вы собираетесь писать составные контейнеры на основе STL, если сравнение итераторов на внутренние контейнеры будет приводить к закрытию программы?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: LaptevVV Россия  
Дата: 06.11.10 17:17
Оценка:
Здравствуйте, Vain, Вы писали:

V>Сравнение валидных итераторов на разные контейнеры одного типа как минимум в MSVC 2005 приводит к закрытию программы.

V>
V>void main()
V>{
V>    std::list<int> a,b;

V>    std::list<int>::iterator i1 = a.end();
V>    std::list<int>::iterator i2 = b.end();

V>    if(i1 != i2) //Boom
V>    {
V>        printf("Just not equal\n");
V>    }
V>}
V>

V>В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?
Вообще-то имеет смысл только два сравнения:
1. Указывают ли оба итератора на начало;
2. Указывают ли оба итератора на конец.
Не могу вообразить, где может потребоваться сравнение итераторов "из середины".
Зачем нужно такое сравнение?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 17:21
Оценка:
Здравствуйте, LaptevVV, Вы писали:

V>>В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?

LVV>Вообще-то имеет смысл только два сравнения:
LVV>1. Указывают ли оба итератора на начало;
LVV>2. Указывают ли оба итератора на конец.
LVV>Не могу вообразить, где может потребоваться сравнение итераторов "из середины".
LVV>Зачем нужно такое сравнение?
В случае составных контейнеров, где в момент сравнения неизвестно на какой подконтейнер указывает итератор, но известно что не должен указывать на конец конкретного подконтейнера.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 17:23
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Может такой "хак" поможет:

CC>
CC>if(&*i1 != &*i2)
CC>

CC>не?
В общем случае, когда можно разъименовать — да. Но надо знать что можно разъименовать — это оверхед как раз.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: STL: Сравнение валидных итераторов на разные контейне
От: BigBoss  
Дата: 06.11.10 19:17
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, CreatorCray, Вы писали:


CC>>Может такой "хак" поможет:

CC>>
CC>>if(&*i1 != &*i2)
CC>>

CC>>не?
V>В общем случае, когда можно разъименовать — да. Но надо знать что можно разъименовать — это оверхед как раз.

Это не оверхед, а воркараунд Но если логика STL не устраивает, то что же должен возвращать оператор != для таких итераторов? И что мешает это именно так и реализовать, раз уж надо
Re[3]: STL: Сравнение валидных итераторов на разные контейне
От: 0xDEADBEEF Ниоткуда  
Дата: 06.11.10 19:28
Оценка:
Здравствуйте, Vain, Вы писали:

V>В случае составных контейнеров, где в момент сравнения неизвестно на какой подконтейнер указывает итератор, но известно что не должен указывать на конец конкретного подконтейнера.

А если в итераторе контейнера хранить, номер подконтейнера и сравнивать сначала номера а затем уже итераторы подконтейнеров? Естественно, если номера в итераторах совпадают...
__________
16.There is no cause so right that one cannot find a fool following it.
Re[4]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 19:52
Оценка:
Здравствуйте, BigBoss, Вы писали:

CC>>>Может такой "хак" поможет:

CC>>>
CC>>>if(&*i1 != &*i2)
CC>>>

CC>>>не?
V>>В общем случае, когда можно разъименовать — да. Но надо знать что можно разъименовать — это оверхед как раз.
BB>Это не оверхед, а воркараунд Но если логика STL не устраивает, то что же должен возвращать оператор != для таких итераторов?
То что и при сравнении обычных указателей. В дополнение он может ассерт кидать, если что-то не так, но не закрывать прогу.
BB>И что мешает это именно так и реализовать, раз уж надо
Что именно это?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 06.11.10 19:53
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

V>>В случае составных контейнеров, где в момент сравнения неизвестно на какой подконтейнер указывает итератор, но известно что не должен указывать на конец конкретного подконтейнера.

DEA>А если в итераторе контейнера хранить, номер подконтейнера и сравнивать сначала номера а затем уже итераторы подконтейнеров? Естественно, если номера в итераторах совпадают...
А чем это отличается от хранения в итераторе указателя на контейнер?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: STL: Сравнение валидных итераторов на разные контейне
От: CreatorCray  
Дата: 06.11.10 23:13
Оценка:
Здравствуйте, Vain, Вы писали:

CC>>Может такой "хак" поможет:

CC>>
CC>>if(&*i1 != &*i2)
CC>>

CC>>не?
V>В общем случае, когда можно разъименовать — да. Но надо знать что можно разъименовать — это оверхед как раз.
Насколько я видел разные имплементации STL кода для итераторов оверхеда как такового в рантайме не будет.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[4]: STL: Сравнение валидных итераторов на разные контейне
От: Vain Россия google.ru
Дата: 07.11.10 04:07
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>>>Может такой "хак" поможет:

CC>>>
CC>>>if(&*i1 != &*i2)
CC>>>

CC>>>не?
V>>В общем случае, когда можно разъименовать — да. Но надо знать что можно разъименовать — это оверхед как раз.
CC>Насколько я видел разные имплементации STL кода для итераторов оверхеда как такового в рантайме не будет.
Здесь
Автор: Vain
Дата: 06.11.10
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: gegMOPO4  
Дата: 07.11.10 14:34
Оценка:
Здравствуйте, Vain, Вы писали:
V>
V>void main()
V>{
V>    std::list<int> a,b;

V>    std::list<int>::iterator i1 = a.end();
V>    std::list<int>::iterator i2 = b.end();

V>    if(i1 != i2) //Boom
V>    {
V>        printf("Just not equal\n");
V>    }
V>}
V>


А вы так не делайте. Ничто не мешает в определённых реализациях некоторым итераторам past-the-end одного типа быть одним и тем же объектом (пример -- итератор односвязного списка). И ничто не мешает оператору равенства быть рассчитанным на сравнение итераторов одного контейнера и давать неправильный результат для разных (пример -- итератор содержит ссылку на контейнер и индекс, при сравнении для оптимизации учитываются только индексы).
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: Erop Россия  
Дата: 08.11.10 06:43
Оценка: 1 (1)
Здравствуйте, Vain, Вы писали:

V>В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?


Лучше всего взять свой список и не страдать.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: STL: Сравнение валидных итераторов на разные контейнеры
От: K13 http://akvis.com
Дата: 08.11.10 07:27
Оценка:
V>Сравнение валидных итераторов на разные контейнеры одного типа как минимум в MSVC 2005 приводит к закрытию программы.
V>В моём случае это не критично и хотелось бы этого избежать. Как переносимо это отключить? Ну или хотябы для конкретных рантаймов?

Отключается дефайнами _HAS_ITERATOR_DEBUGGING=0 _SECURE_SCL=0
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.