Почему строка использования:: итератор, а не индекс? [дубликат]

Возможный дубликат:
Почему итераторы использования вместо индексов массива?

string::iterator it;
for (it = str.begin(); it < str.end(); it++) 
    cout << *it;
cout << endl;

Почему нет:

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

Кажется что строка:: итератор не обеспечивает проверку принадлежности к диапазону также. Почему мы должны использовать string::iterator а не индекс?

Спасибо.

38
задан Community 23 May 2017 в 12:34
поделиться

10 ответов

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

Итератор предлагает унифицированный способ доступа к любой структуре коллекции/данных. Гибкость при рефакторинге кода огромна.

.
27
ответ дан 27 November 2019 в 03:47
поделиться

Предполагаю, что еще одна причина, по которой итераторы следует отдавать предпочтение индексам, заключается в том, что не все коллекции поддерживают постоянный случайный доступ.

Например, если вы хотите, чтобы n-элемент в связанном списке, вам необходимо пройти все предыдущие элементы (с индексами 0...n-1) до тех пор, пока вы не доберетесь до n-элемента. (Эта операция занимает линейное время.)

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

.
0
ответ дан 10 October 2019 в 00:48
поделиться

Итераторы - стандартный интерфейс. Используя итераторы, можно использовать одни и те же алгоритмы с разными контейнерами. Окончательное решение о том, использовать их или нет, зависит от удобства использования и читаемости.

Например, использование стандартного алгоритма преобразования для сокрытия std::string в верхний регистр:

std::string str = "A String";
std::transform(str.begin(), str.end(), str.begin(), ::toupper);

приведет к тому, что str будет равно "A STRING".

.
18
ответ дан 27 November 2019 в 03:47
поделиться

Для std::string я бы предложил использовать индексы, так как он поддерживает случайный доступ и проще. Единственная причина, по которой "рекомендуется" использовать итераторы, заключается в том, что итераторы предлагают стандартный интерфейс для доступа к последовательностям таким образом, что если, например, ваша последовательность изменится на std::list, то код вашей итерации останется неизменным

.
6
ответ дан 27 November 2019 в 03:47
поделиться

Как сказано в этом вопросе, метод size() не гарантирован O(1)

.
1
ответ дан 27 November 2019 в 03:47
поделиться

В случаях, когда вы не знаете, над каким классом вы проводите итерацию (потому что это аргумент шаблона), вы должны использовать итератор, потому что не каждый класс, который предоставляет итератор, также предоставляет [] (и не каждый класс, который предоставляет [], предоставляет класс, который работает во времени O(1)). Таким образом, используя итератор, вы убедитесь, что функция будет работать с как можно большим количеством классов (хотя и не с массивами C).

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

.
1
ответ дан 27 November 2019 в 03:47
поделиться

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

.
0
ответ дан 27 November 2019 в 03:47
поделиться

В C++ можно делать много разных вещей. Это еще один пример. В данном случае нет никакой разницы, какой метод использовать. Но в целом итераторы быстрее, безопаснее и обеспечивают большую гибкость при работе с разными типами контейнеров.

.
-2
ответ дан 27 November 2019 в 03:47
поделиться

Дубликат:

  1. Итераторы... зачем их использовать?
  2. Зачем использовать итераторы вместо индексов массивов?

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

Наконец, есть вопрос безопасности в итерации. Если вы хотите получить доступ к символу NEXT в вашем цикле, то с итераторами это можно сделать безопасно, но увеличение подскрипта массива может привести к сегментации на последнем элементе, следовательно, потребуется еще одна проверка

.
2
ответ дан 27 November 2019 в 03:47
поделиться

Оба работает.

Основной причиной будет последовательность: вы одинаково итерацируете над коллекцией или символами строки, запрашивая итератор и делая его вперед.

Не скажу, что стоит упомянуть подробности реализации ++it, приводящей к увеличению указателя по сравнению с str[i] с использованием арифметики с указателями. А проверка диапазона также является детализацией реализации

.
0
ответ дан 27 November 2019 в 03:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: