Инициализация итераторов
От: nut888 Россия  
Дата: 25.01.08 05:47
Оценка:
Какие есть способы проверить был ли итератор инициализирован чем либо или нет

Например

/**********************************************/
std::vector<int> data;
std::vector<int>::iterator it;

for(std::vector<int>::iterator i=data.begin(); i!=data.end(); ++i)
if(...) it=i;

if(???) *it; // Обращение по итератору
/*********************************************/


Также интересует возможность проверки валидности итератора it
Re: Инициализация итераторов
От: Аноним  
Дата: 25.01.08 05:50
Оценка:
N>Также интересует возможность проверки валидности итератора it
Здесь я подразумеваю например вызов push_back между инициализацией и использованием
Re: Инициализация итераторов
От: jazzer Россия Skype: enerjazzer
Дата: 25.01.08 05:58
Оценка:
Здравствуйте, nut888, Вы писали:

N>Какие есть способы проверить был ли итератор инициализирован чем либо или нет

N>Также интересует возможность проверки валидности итератора it

Воспользоваться отладочным режимом STLport.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Инициализация итераторов
От: Аноним  
Дата: 25.01.08 08:25
Оценка:
Здравствуйте, nut888, Вы писали:

N>Какие есть способы проверить был ли итератор инициализирован чем либо или нет


N>Например


N>
N>/**********************************************/
N>std::vector<int> data;
N>std::vector<int>::iterator it;

N>for(std::vector<int>::iterator i=data.begin(); i!=data.end(); ++i)
N>if(...) it=i;

N>if(???) *it; // Обращение по итератору
N>/*********************************************/
N>


N>Также интересует возможность проверки валидности итератора it


1. Инициализацию нельзя проверить, используйте свой флажок
2. изменение (push_back) вектора вполне себе инвалидирует ваш итератор, и об этом вы тоже не узнаете.
В целом, итератор это такая временная штука, которую лучше использовать так — взял, попользовался, забыл. Долгосрочное хранение итераторов — вешь сложная, это конечно можно делать, но это почти всегда грабли, пожалуй за исключением неизменяемых контейнеров.
Re[2]: Инициализация итераторов
От: Left2 Украина  
Дата: 25.01.08 08:36
Оценка:
А>2. изменение (push_back) вектора вполне себе инвалидирует ваш итератор, и об этом вы тоже не узнаете.

Насколько я понимаю для вектора это запросто можно узнать сравнив между собой size и capacity. Знатоки стандарта, поправьте если не прав.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[2]: Инициализация итераторов
От: rg45 СССР  
Дата: 25.01.08 09:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>[snipped]

А>2. изменение (push_back) вектора вполне себе инвалидирует ваш итератор, и об этом вы тоже не узнаете.

Это такая штука, которая зависит от реализации. В StlPort, например, итераторы в дебажной и релизной (извините за использование сленга) конфигурациях представлены разными типами. Конкретно, итератор вектора в релизной конфигурации — это обычный указатель, а в дебажной — структура, содержащая дополнительную информацию, которая как раз и позволяет диагностировать использование инвалидированных итераторов (при попытке использования инвалидного итератора возбуждается исключение).
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Инициализация итераторов
От: AntiFreeze  
Дата: 25.01.08 16:19
Оценка: -1
Здравствуйте, Left2, Вы писали:

А>>2. изменение (push_back) вектора вполне себе инвалидирует ваш итератор, и об этом вы тоже не узнаете.


L>Насколько я понимаю для вектора это запросто можно узнать сравнив между собой size и capacity. Знатоки стандарта, поправьте если не прав.


iter >= begin() && iter < end()
Re: Инициализация итераторов
От: Alex Alexandrov США  
Дата: 25.01.08 19:42
Оценка:
Здравствуйте, nut888, Вы писали:

N>Какие есть способы проверить был ли итератор инициализирован чем либо или нет


В данном конкретном случае все, кажется, проще:
/**********************************************/
std::vector<int> data;
std::vector<int>::iterator i;

for (i = data.begin(); i != data.end(); ++i)
    if (...)
        break;

if (i != data.end())
    *it; // Обращение по итератору


Рекомендация по стилю, кстати — в фигурные скобки лучше обрамлять даже один оператор в if/for/...
Ибо написать что-то вроде

if (i != data.end())
    LOGLN("accessing the iterator");
    *it; // Обращение по итератору


очень легко, а вот отладить потом — не очень...

N>Также интересует возможность проверки валидности итератора it

Хороший STL подскажет assert-ом
It's kind of fun to do the impossible (Walt Disney)
Re[4]: Инициализация итераторов
От: Left2 Украина  
Дата: 26.01.08 09:46
Оценка:
AF>iter >= begin() && iter < end()
ага, а 6 x 8 = 48
Это к чему вообще, простите?
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[3]: Инициализация итераторов
От: rg45 СССР  
Дата: 26.01.08 09:57
Оценка: 10 (1)
Здравствуйте, Left2, Вы писали:

А>>2. изменение (push_back) вектора вполне себе инвалидирует ваш итератор, и об этом вы тоже не узнаете.


L>Насколько я понимаю для вектора это запросто можно узнать сравнив между собой size и capacity. Знатоки стандарта, поправьте если не прав.


size и capacity чаще всего не равны друг другу и на их сравнении врядли можно сделать какие-то выводы о валидности итераторов. Может быть, ты хотел сказать: сравнив capacity до и после вставки? Ведь инвалидация итераторов вектора происходит в результате реаллокации памяти при изменении рамера памяти, выделенной для элементов вектора. Да, практически, такое решение наверное прокатит — врядли в какой либо реализации STL разработчикам может прийти в голову делать реаллокацию без изменения capacity. Но, если говорить строго, то в стандарте нигде не сказано, что если после вставки элемента capacity не изменилось, то реаллокации не было.
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Инициализация итераторов
От: Left2 Украина  
Дата: 26.01.08 10:32
Оценка: 6 (1)
L>>Насколько я понимаю для вектора это запросто можно узнать сравнив между собой size и capacity. Знатоки стандарта, поправьте если не прав.
R>Может быть, ты хотел сказать: сравнив capacity до и после вставки?
Не совсем так — сравнив size и capacity до вставки. Хотя насчёт сравнения capacity до и после вставки — это идея получше Ведь теоретически имплементация может делать переаллокацию ещё до того, как закончилось capacity, хотя практически трудно себе представить ситуацию когда это было бы оправдано.

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

Жаль что стандартом это не оговорено. Но в любом случае спасибо за разьяснения
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[5]: Инициализация итераторов
От: rg45 СССР  
Дата: 26.01.08 11:14
Оценка:
Здравствуйте, Left2, Вы писали:

L>>>Насколько я понимаю для вектора это запросто можно узнать сравнив между собой size и capacity. Знатоки стандарта, поправьте если не прав.

R>>Может быть, ты хотел сказать: сравнив capacity до и после вставки?
L>Не совсем так — сравнив size и capacity до вставки...

Теперь понял идею. Наверное тоже должно работать. Но, опять же, слабость обоих приемов в том, что они основаны на предположениях о реализации и не подкреплены стандартом. А кроме того, на практике чаще всего бывает, что в том месте, где происходит вставка, владельцы итераторов не известны, и освежить эти итераторы нет возможности, в этом случае, спасает только переход от вектора к списку.
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Инициализация итераторов
От: AlexCrush Россия  
Дата: 27.01.08 10:14
Оценка: +2
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Аноним, Вы писали:


А>>[snipped]

А>>2. изменение (push_back) вектора вполне себе инвалидирует ваш итератор, и об этом вы тоже не узнаете.

R>Это такая штука, которая зависит от реализации. В StlPort, например, итераторы в дебажной и релизной (извините за использование сленга) конфигурациях представлены разными типами. Конкретно, итератор вектора в релизной конфигурации — это обычный указатель, а в дебажной — структура, содержащая дополнительную информацию, которая как раз и позволяет диагностировать использование инвалидированных итераторов (при попытке использования инвалидного итератора возбуждается исключение).


Это всё конечно здорово, но использовать это можно лишь при отладке. Если же кому-то придет в голову использовать это в нормальном коде — руки надо отрывать. Потому что, как Вы сказали, "это зависит от реализации".
Re[5]: Инициализация итераторов
От: Erop Россия  
Дата: 27.01.08 19:52
Оценка: 1 (1)
Здравствуйте, Left2, Вы писали:

L>Не совсем так — сравнив size и capacity до вставки. Хотя насчёт сравнения capacity до и после вставки — это идея получше Ведь теоретически имплементация может делать переаллокацию ещё до того, как закончилось capacity, хотя практически трудно себе представить ситуацию когда это было бы оправдано.


А вдруг, например, vector разделяет тело между несколькими копиями объекта? И при любых модификациях может сделать переаллокацию, соответсвенно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Инициализация итераторов
От: rg45 СССР  
Дата: 27.01.08 20:27
Оценка:
Здравствуйте, Erop, Вы писали:

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


L>>Не совсем так — сравнив size и capacity до вставки. Хотя насчёт сравнения capacity до и после вставки — это идея получше Ведь теоретически имплементация может делать переаллокацию ещё до того, как закончилось capacity, хотя практически трудно себе представить ситуацию когда это было бы оправдано.


E>А вдруг, например, vector разделяет тело между несколькими копиями объекта? И при любых модификациях может сделать переаллокацию, соответсвенно?


Интересная мысль, но мне кажется, трудно реализуемая. В самом деле, тогда для того, чтобы прошла переаллкокация и инвалидировались итераторы, достаточно не вставки или удаления элемента, а простого изменения значения какого-либо элемента. Такой эффект со стандартом не соглсуется. Ну или нужно прекращать совместное использование содержимого при получении первого же итератора. Но тогда возникает вопрос: а стоит ли игра свеч?
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[7]: Инициализация итераторов
От: Erop Россия  
Дата: 27.01.08 20:59
Оценка:
Здравствуйте, rg45, Вы писали:

R>Интересная мысль, но мне кажется, трудно реализуемая. В самом деле, тогда для того, чтобы прошла переаллкокация и инвалидировались итераторы, достаточно не вставки или удаления элемента, а простого изменения значения какого-либо элемента. Такой эффект со стандартом не соглсуется. Ну или нужно прекращать совместное использование содержимого при получении первого же итератора. Но тогда возникает вопрос: а стоит ли игра свеч?


При получении первого неконстантного.
В целом скорее всего не стоит. Но кто его знает...
Вдруг в какой-нибудь версии будут параноидально экономить память?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Инициализация итераторов
От: rg45 СССР  
Дата: 27.01.08 22:55
Оценка:
Здравствуйте, Erop, Вы писали:

E>При получении первого неконстантного.

Не получается. Потому, что если мы последовательно получаем два итератора — первый константный, второй — неконстантный, то при получении второго происходит реаллокация и первый становится невалидным (или того хуже — валидным, но ссылающимся на содержимое не того контейнера).
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[9]: Инициализация итераторов
От: Erop Россия  
Дата: 28.01.08 16:23
Оценка:
Здравствуйте, rg45, Вы писали:

R>Не получается. Потому, что если мы последовательно получаем два итератора — первый константный, второй — неконстантный, то при получении второго происходит реаллокация и первый становится невалидным (или того хуже — валидным, но ссылающимся на содержимое не того контейнера).


Да, так не получится.
Зато можно в итераторе хранить указатель на вектор и индекс. Будет медленнее, зато можно не копировать.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.