Я обнаружил, что много писал:
int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();
/..../
std::advance(it, location);
вместо
it= it + 5;
Каков предпочтительный/рекомендуемый способ?
Я обнаружил, что много писал:
int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();
/..../
std::advance(it, location);
вместо
it= it + 5;
Каков предпочтительный/рекомендуемый способ?
Добавление будет работать только с итераторами с произвольным доступом. std :: advance будет работать со всеми видами итераторов. Пока вы имеете дело только с итераторами в векторах, это не имеет никакого значения, но std :: advance сохраняет ваш код более универсальным (например, вы можете заменить список вектором, и эта часть будет работать).
Для тех, кому это небезразлично, стандарт описывает advance
и distance
следующим образом (§24.3.4/1):
Так как только итераторы с произвольным доступом предоставляют операторы + и -, библиотека предоставляет два шаблона функций для
advance
иdistance
. Эти шаблоны функций используют+
и-
для итераторов произвольного доступа (и, следовательно, имеют для них постоянное время); для входных, прямых и двунаправленных итераторов они используют++
для обеспечения реализации линейного времени.
Это зависит от того, что вам нужно:
Если вам нужна общая, используйте std::advance(it,2)
. Если кто-то приходит и меняет ваш std::vector
на std::list
, код все равно будет компилироваться, хотя наступление теперь требует линейного времени вместо постоянного времени.
Если вам нужна производительность, используйте it+=2
. Если кто-то приходит и меняет ваш std::vector
на std::list
, код не будет компилироваться, указывая (возможно, с полезным комментарием) на серьезную проблему с производительностью.
Это зависит от итератора. it=it+5
работает быстрее, если поддерживается (поддерживается только для итераторов произвольного доступа). Если вы хотите продвинуть менее эффективный итератор (например, форвардный итератор или двунаправленный итератор), вы можете использовать std::advance
, но он медленнее, потому что он фактически просматривает все промежуточные элементы.
std::advance
работает также и для неслучайных итераторов, а версия +=
работает над последовательностями произвольного доступа (векторы и т.п.).
std::adnvance
является общим - полезно, если вы не всегда знаете тип базового контейнера - он работает во всех случаях.
Однако он эффективен: std::advance
будет делать оптимизацию, если он передал RandomAccessIterator (например, один из std::vector
) и увеличит итератор в цикле для ForwardAccessIterator (как один в std::list
).
Используйте std:: advance. Он так же эффективен (он использует итераторные черты, чтобы просто добавлять итератор для итераторов произвольного доступа), и является более общим в том, что он работает и с другими типами итераторов.
Если вы никогда не собираетесь менять контейнер (а вы, вероятно, нет), используйте +, потому что он легко видит и понимает и оставляет код менее загроможденным.
Если вы считаете, что хотите изменить контейнер, или если вы работаете внутри шаблона, который может быть создан в разных типах контейнеров, используйте заранее, потому что он работает с чем-либо.
Как правило, я не беспокоюсь об изменении типов контейнеров, потому что обнаружил, что когда мне нужно изменить тип контейнера, я в конечном итоге пересматриваю везде, где используется контейнер, просто чтобы быть уверенным, m не делает ничего, что внезапно глупо (например, случайно выщипывая элементы из середины списка).