2013-02-26 5 views
2

Зачем использовать итераторы?В чем смысл итераторов?

Например, если у меня есть такой код:

for (int i = 0; i < vec.size(); i++) 
    cout << vec[i]; 

, что было бы преимущество написания

for (vector<int>::iterator it != vec.begin(); it != n.end(); ++it) 
    cout << *it; 

Кроме того, почему пишет i < vec.size() и i++ более распространенным в первом примере и it != begin() и ++it более распространены во втором примере? В чем разница, как вы его увеличиваете и почему не всегда используете знак равенства?

Я понимаю, что итераторы могут быть полезны в цикле C++ 11 для циклов и некоторых алгоритмах STD, но почему я должен делать это в обычном коде, поскольку он более подробный?

+1

Это должно покрыть: http://stackoverflow.com/questions/131241/why-use -тераторы-вместо-массивные-индексы http://stackoverflow.com/questions/178934/iterators-why-use-them – chm

+0

Что делать, если vec - это список? – billz

+0

Не так хорошо, как 'std :: for_each (begin (vec), end (vec), [] (int x) {std :: cout << x;});'. Избегайте побочных ошибок и других ошибок, которые могут быть ошибочно приняты: используйте алгоритмы и диапазоны итераторов вместо рукописных циклов. –

ответ

2

Ну, не все контейнеры имеют произвольный доступ, поэтому вы можете выполнять поиск по индексу, поэтому для нормализации итераторов интерфейса довольно полезны. Рассмотрим std::list. Он не поддерживает произвольный доступ через оператора [].

Принимая это во внимание, чтобы работать во многих гетерогенных типах контейнеров, многие функции STL, такие как std :: copy, принимают итераторы.

0

Дело в том, что итераторы позволяют вам перебирать на все, что поддерживает итераторы в общем виде.

Что касается более подробной информации, то дополнительная многословность не является ужасной (и ваш пример может быть немного улучшен с использованием auto или с использованием цикла на основе C++ 11), но это действительно стилистическая проблема.

1

Допустим, у нас есть этот код:

typedef std::vector<std::string> strings; 

strings strs; 
for(strings::const_iterator it = strs.begin(); it != strs.end(); ++it) { 
} 

И позже watever причине мы решили переключиться на STD :: список. Поэтому мы просто заменяем typedef и код:

typedef std::list<std::string> strings; 

strings strs; 
for(strings::const_iterator it = strs.begin(); it != strs.end(); ++it) { 
} 

Будет работать как раньше. Но код с индексной переменной не сработает. Представьте, что, если вам нужно написать код шаблона.