Подтвердить что ты не робот

Зачем использовать string:: iterator вместо индекса?

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

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 не предоставляет проверку диапазона. Почему мы должны использовать string::iterator вместо индекса?

Спасибо.

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

Дубликат:

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

Оба работают.

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

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

Ответ 8

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

Ответ 9

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

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

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

Ответ 10

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