Для тех, кто читает это сейчас, вопрос стал чем-то спорным с C ++ 11.
Я не был уверен, квалифицируется ли этот ответ как ответ, потому что он на самом деле не касается сути вопроса. Но я действительно считаю правильным указать, что проблема, поднятая здесь, будет редко встречаться на практике для программиста на C ++ 11, и я определенно нашел бы этот ответ полезным несколько лет назад. Поэтому этот ответ нацелен на читателя, который просто хочет знать, лучший способ перебора всех элементов в контейнере STL (vector
, list
, deque
и т. Д.).
Предполагая, что OP хотел получить доступ к каждому элементу в контейнере, мы можем легко обойти весь вопрос о том, является ли определение end
достаточно быстрым, чем вызов Container::end()
, написав на основе диапазона для цикла :
Container container; // my STL container that has been filled with stuff
// (note that you can replace Container::value_type with the value in the container)
// the standard way
for (Container::value_type element : container) {
// access each element by 'element' rather than by '*it'
}
// or, if Container::value_type is large
Container container; // fill it with something
for (Container::value_type& element : container) {
//
}
// if you're lazy
Container container; // fill it with something
for (auto element : container) {
//
}
ОП спросил, стоит ли компромисс между краткостью простого сравнения it
с Container::end()
на каждой итерации и эффективностью объявления переменной end
и сравнения этого значения на каждом шаге. Поскольку циклы for на основе диапазона предоставляют простую, легкую в написании и легкую для чтения альтернативу, которая также внутренне объявляет итератор end
, а не вызывает метод Container::end()
на каждом шаге, количество случаев, когда нам нужно Чтобы остановиться на этом вопросе было сведено к ограниченному числу случаев.
Согласно cppreference.com , цикл for на основе диапазона будет генерировать код с такими же побочными эффектами, как показано ниже:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr,
__end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}