Первый быстрее, потому что end()
не вызывается на каждой итерации. И нет, оптимизатор не может легко кешировать это для вас, потому что он не знает, изменился ли размер контейнера в этой итерации (и, следовательно, конец перемещен). Это также относится к const-контейнеру из-за проблемы с алиасами.
i++
возвращает копию i, затем увеличивает. ++i
увеличивается, затем возвращает увеличенное значение. Следовательно, когда вы отбрасываете возвращаемое значение, используйте ++i
, потому что оно должно выполнять меньше работы (без копирования). Оптимизатор, скорее всего, исправит встроенный вызов i++
, так что он так же быстр, как ++i
, но не полагайтесь на это.
Me? Я использую
for(int i = 0; i < m.size(); i++) {
// ... do something with m[i]
}
Потому что это самый короткий и самый понятный. Почему int
, а не MyClass::size_type
? Потому что это проще, и мне никогда не приходилось беспокоиться о крайних случаях. Почему i++
? Потому что для базовых типов он всегда оптимизирован до ++i
, и это менее запутанно для коллег. В качестве бонуса я также могу использовать i
в качестве числового значения. С итератором мне пришлось бы вести отдельный счетчик или использовать std::distance
.
obecalp указывает, что это не работает с половиной стандартных контейнеров, таких как list
и map
. На самом деле те требуют использования правильного итератора. Кроме того, вы всегда должны использовать iterator
при написании универсального кода.