Нет, это неправильный способ сделать это. Для ::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
, чтобы возвращать итераторные вещи.
Возможно, вы используете 'size_t' вместо' unsigned int'. – Maxpm
@Maxpm - Или, еще лучше, ':: std :: vector :: size_type'. –
Omnifarious
begin() и end() имеют гарантированную сложность O (1). Хотя размер имеет только гарантию O (n) на общих контейнерах (хотя строка и вектор могут иметь дополнительные гарантии по родовому признаку). –