Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> STL::Контейнеры, iterator VS (operator[] || at()) 
V
    Опции темы
Dray
Дата 11.6.2006, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



В стандартных контейнерах в каких задачах предпочтительнее пользоваться итераторами, а в каких оператором [] или at()'ом? Что работает быстрее всех? И если в каком-то случае одинаково логично использовать итератор и оператор [] что лучше выбрать? 


--------------------
忍者

user posted image
PM MAIL   Вверх
maxim1000
Дата 11.6.2006, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



at делает проверку на выход за границы массива
[] - нет

at медленнее, но безопаснее... 


--------------------
qqq
PM WWW   Вверх
Dray
Дата 11.6.2006, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Цитата(maxim1000 @  11.6.2006,  17:58 Найти цитируемый пост)
at медленнее, но безопаснее...

Да, совсем недавно с этим столкнулся. Использовал сначала [] программа вытворяла что хотела, причем явной ошибки небыло, никаких exception'ов не вылетало. Но зато чертовщина творилась, чуть ли не жанглирование кнопками на форме. Думал с ума сойду когда ошибку искал. Поменял некоторые [] на at'ы, тут же схватил исключение, оказалось выход за пределы границы .smile
А что насчет скорости и безопасности итераторов по сравнению с []? 


--------------------
忍者

user posted image
PM MAIL   Вверх
SaDFromSpb
Дата 11.6.2006, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Оператор [] работает так же, как и с обычными массивами. То есть берет адресс первого элемента контейнера и прибавляет число в скобках, получая адресс нужного элемента. И никаких проверок во имя скорости. Все элементы контейнера, который поддерживает оператор [], располагаются в памяти непрерывно - это требование стандарта, как мне тут умные люди подсказали.
Следовательно по скорости самое быстрое - это оператор [].
Что из возможных средств доступа к элементу выбрать, зависит от случая. Если требуется пройтись по всем элементам в прямом или обратном порядке, то быстрее воспользоваться итератором, наверное; или вообще использовать for_each().  

Это сообщение отредактировал(а) SaDFromSpb - 11.6.2006, 19:30


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
Daevaorn
Дата 11.6.2006, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Dray, Во первых не во всех контейнерах STL есть operator[] или at(). Тогда выбора просто не остается. Что касается контейнеров, которые располагают свои элементы последовательно( vector, stack и т.д. ), то в релизной версии,практически всегда, итератор == указатель на элемент, что есть хорошо. Практически оптимальный вариант. При грамотном использовании итераторы вполне безопасны с точки зрения исключений. Но надо всегда иметь ввиду, что после многих "изменяющих последовательность" операций, итератор становится недействительным. 
PM MAIL WWW   Вверх
Void
Дата 11.6.2006, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(SaDFromSpb @  11.6.2006,  21:28 Найти цитируемый пост)
Все элементы контейнера, который поддерживает оператор [], располагаются в памяти непрерывно - это требование стандарта, как мне тут умные люди подсказали.

map 


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
DeadSoul
Дата 11.6.2006, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Dray @  11.6.2006,  18:42 Найти цитируемый пост)
Думал с ума сойду когда ошибку искал. Поменял некоторые [] на at'ы, тут же схватил исключение, оказалось выход за пределы границы .

Это проблема не операторов, а твоя

Цитата(Dray @  11.6.2006,  18:42 Найти цитируемый пост)
А что насчет скорости и безопасности итераторов по сравнению с []?  

Никак. В релизе практически никак. В дебаге получишь ассерты.  Например, для вектора в релизе итераторы практически всегда - обычне указатели

Цитата(Void @  11.6.2006,  20:01 Найти цитируемый пост)
Цитата(SaDFromSpb @  11.6.2006,  21:28 )
Все элементы контейнера, который поддерживает оператор [], располагаются в памяти непрерывно - это требование стандарта, как мне тут умные люди подсказали.
map  

В точку.
 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
SaDFromSpb
Дата 11.6.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



DeadSoul, Void,
А блин! Забыл про map забыл...  smile 


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
ZeusAtVingrad
Дата 11.6.2006, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.4.2006

Репутация: нет
Всего: нет



Цитата(Daevaorn @ 11.6.2006,  19:30)
Что касается контейнеров, которые располагают свои элементы последовательно( vector, stack и т.д. )

А зачем stack'у располагать элементы последовательно?  

Это сообщение отредактировал(а) ZeusAtVingrad - 11.6.2006, 23:49
PM MAIL   Вверх
DeadSoul
Дата 12.6.2006, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(ZeusAtVingrad @  11.6.2006,  23:46 Найти цитируемый пост)
А зачем stack'у располагать элементы последовательно?  

А стек - не есть контейнер, это контейнерный адаптер(и как оно называется) 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
ZeusAtVingrad
Дата 12.6.2006, 00:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.4.2006

Репутация: нет
Всего: нет



Э-э, и что?
Я про саму структуру данных "стек" говорю: для её функциональности последовательное размещение данных в памяти не обязательно. 
PM MAIL   Вверх
np9mi7
  Дата 12.6.2006, 01:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 553
Регистрация: 17.8.2003
Где: Volgograd, Russia

Репутация: 5
Всего: 10



at с исключением, [] как правило с assert - ом... Просто часто [] инкапсулирует в себе дополнительные действия (например поиск в map и ему подобных).

Поэтому вот что-то типа этого:
Код

typedef ::std::map <size_t, int> MyMap;

MyMap _L_MyMap;

_L_MyMap.insert ( ::std::pair 
    <size_t, int> (1, 1));

_L_MyMap.insert ( ::std::pair 
    <size_t, int> (2, 1));

_L_MyMap.insert ( ::std::pair 
    <size_t, int> (3, 1));

_L_MyMap.insert ( ::std::pair 
    <size_t, int> (4, 1));

_L_MyMap.insert ( ::std::pair 
    <size_t, int> (5, 1));
    
for (size_t _L_Index = 1; _L_Index != 6; 
    _L_MyMap [_L_Index] += 1, ++ _L_Index) {;}  ///  тут лишний поиск

Можно заменить стандартным алгоритмом с использованием итераторов:
Код

void Add (::std::pair <const size_t, int> & _P_Pair)
{
    _P_Pair.second += 1;
}

::std::for_each (_L_MyMap.begin (), 
    _L_MyMap.end (), ::Add);
, короче все вообще зависит от задачи. Но если программировать в стиле STL, то это стандартные алгоритмы и итераторы; 


--------------------
"Я точно знаю то, что ничего не знаю..." Сократ.
evolution project
PM MAIL WWW ICQ MSN   Вверх
DeadSoul
Дата 12.6.2006, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



np9mi7, а в чем смысл твоего примера?

Добавлено @ 11:00 
Цитата(ZeusAtVingrad @  12.6.2006,  00:53 Найти цитируемый пост)
Я про саму структуру данных "стек" говорю: для её функциональности последовательное размещение данных в памяти не обязательно.  

А это не обязательно вектор
Цитата

23.2.3.3 Class template stack
Any sequence supporting operations back(), push_back() and pop_back() can be used instantiate
stack. In particular, vector (23.2.4), list (23.2.2) and deque (23.2.1) can be used.

(с)С++ Стандарт 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
np9mi7
Дата 12.6.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 553
Регистрация: 17.8.2003
Где: Volgograd, Russia

Репутация: 5
Всего: 10



Цитата
np9mi7, а в чем смысл твоего примера?

Цитата
Просто часто [] инкапсулирует в себе дополнительные действия (например поиск в map и ему подобных).

Код

_L_MyMap [_L_Index] += 1, ++ _L_Index) {;}  ///  тут лишний поиск
 
Код

::std::for_each (_L_MyMap.begin (), 
    _L_MyMap.end (), ::Add);                               /// тут лишнего поиска нет, потому что используется итератор, поэтому в данном конкретном случае предпочтительнее использовать итератор вместо [] или at
 

Это сообщение отредактировал(а) np9mi7 - 12.6.2006, 13:46


--------------------
"Я точно знаю то, что ничего не знаю..." Сократ.
evolution project
PM MAIL WWW ICQ MSN   Вверх
ZeusAtVingrad
Дата 12.6.2006, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.4.2006

Репутация: нет
Всего: нет



Цитата(DeadSoul @ 12.6.2006,  10:57)
np9mi7, а в чем смысл твоего примера?

Добавлено @ 11:00 
Цитата(ZeusAtVingrad @  12.6.2006,  00:53 Найти цитируемый пост)
Я про саму структуру данных "стек" говорю: для её функциональности последовательное размещение данных в памяти не обязательно.  

А это не обязательно вектор
Цитата

23.2.3.3 Class template stack
Any sequence supporting operations back(), push_back() and pop_back() can be used instantiate
stack. In particular, vector (23.2.4), list (23.2.2) and deque (23.2.1) can be used.

(с)С++ Стандарт

Что-то всё-равно не пойму куда ты разговор уводишь, ну да ладно, проехали. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0574 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.