Нет, это не правильный способ сделать это.Для ::std::vector
или ::std::string
он работает нормально, но проблема в том, что если вы когда-либо используете что-то еще, это не будет работать так хорошо.Кроме того, это не идиоматично.
И, чтобы ответить на ваш другой вопрос ... Функция size
, вероятно, встроенная.Это означает, что он, скорее всего, просто извлекает значение из внутренних элементов ::std::string
или ::std::vector
.Компилятор оптимизирует это и извлекает его только один раз в большинстве случаев.
Но вот идиоматический способ:
for (::std::vector<Foo>::iterator i = theContainer.begin();
i != theContainer.end();
++i)
{
Foo &cur_element = *i;
// Do stuff
}
++i
очень важен.Опять же, для ::std:vector
или ::std::string
, где итератор является в основном указателем, это не так важно.Но для более сложных структур данных это так.i++
должен сделать копию и создать временную, потому что старое значение должно остаться.++i
не имеет такой проблемы.Привыкайте всегда использовать ++i
, если только у вас нет веских причин не делать этого.
Наконец, theContainer.end()
также будет в целом оптимизировано как не существующее.Но вы можете заставить вещи быть немного лучше, сделав это:
const ::std::vector<Foo>::iterator theEnd = theContainer.end();
for (::std::vector<Foo>::iterator i = theContainer.begin(); i != theEnd; ++i)
{
Foo &cur_element = *i;
// Do stuff
}
Конечно, C ++ 0x значительно упрощает все это благодаря новому синтаксису для циклов for
:
for (Foo &i: theContainer)
{
// Do stuff with i
}
Они будут работать со стандартными массивами фиксированного размера, а также с любым типом, который определяет begin
и end
для возврата объектов, подобных итератору.