Вопрос

for (int i = 0 ; i < stlVector.size() ; i++)
{ 
    if (i == 10)
    { 
        stlVector.erase(stlVector.begin() + 5 )
    }
}

Учитывает ли часть условия завершения "stlvector.size ()" stlvector.erase (...) "?Другими словами, обновляется ли stlVector.size() для каждой итерации цикла?Я не могу проверить это прямо сейчас, поэтому я задал вопрос здесь.

Спасибо заранее!

С наилучшими пожеланиями,

Женгтоник

Это было полезно?

Решение

Чтобы внести ясность: не думайте об этом как о том, что цикл что-то обновляет.Каждый раз, когда условие проверяется (в начале каждого цикла), метод size() вызывается для переменной stlVector и возвращается текущий размер вектора.

Метод стирания() уменьшает размер вектора, поэтому при следующем вызове метода size() возвращаемое значение будет меньше.

Другие советы

Да!

stlVector.size () // is called for evey iteration

Таким образом, для каждого цикла вам придется переоценивать тест «i < stlVector.size ()»!

Да, тест проводится с побочными эффектами для каждой петли.

Цикл for — это всего лишь приятное соглашение: цикл for легко разлагается на цикл while:

for (int i = 0 ; i < stlVector.size() ; i++)
{ 
    if (i == 10)
    { 
        stlVector.erase(stlVector.begin() + 5 )
    }
}

Становится:

int i = 0 ;

while(i < stlVector.size())
{ 
    if (i == 10)
    { 
        stlVector.erase(stlVector.begin() + 5 )
    }
    i++;
}

-Адам

Да, это так, но не делайте этого!Если вы хотите удалить элементы из вектора, сделайте это внутри другого цикла.В этом случае вы удаляете элементы после индекса i:ничто не гарантирует, что элемент stlVector[i+5] существует.Если вы удалите i-й элемент из вектора, ваш счетчик будет нарушен, потому что вы можете переходить через элементы, не проверяя их.

Самый безопасный способ сделать это — сохранить ссылки на элементы stlVector, которые вы хотите удалить, в другом векторе, а затем выполнить итерацию по этому вспомогательному вектору, выполнив stlVector.erase(auxVector[i]).

Я ожидаю, что предоставленный вами код - это просто «фантастический код» (как выразился один комментатор), чтобы дать конкретный пример того, что вы пытаетесь сделать.

Однако на всякий случай это не так: цикл, который вы дали, пропустит 12-й элемент (т.е.элемент изначально в stlVector[11]), потому что при осмотре stlVector[10] вы удаляете более ранний элемент, в результате чего все последующие элементы перемещаются на одну позицию вперед, но вы все равно увеличиваете i в конце цикла.Итак, следующая итерация будет рассматривать stlVector[11] который на самом деле является элементом, который изначально был в stlVector[12].Чтобы это исправить, вам необходимо --i после звонка в erase().

Всегда переоценивайте обязательно!

Кроме того, чтобы немного уточнить, поскольку вы спросили, сделано ли это таким образом «в VC++ 6».

«Условие продолжения» пересчитывается в каждом цикле в КАЖДОЙ версии C, C++, C# и Java.

Если какой-либо компилятор не генерирует код, который это делает, он сломан и должен избегать.

Как говорили другие, да, условие переоценивается каждый раз в цикле.Вот почему обычная оптимизация производительности:

int saveSize = someExpensiveComputation();

for (int i = 0 ; i < saveSize ; i++)
{ 
    foo(i);
}

где условие цикла вообще требует больших затрат для вычисления, а не

for (int i = 0 ; i < someExpensiveComputation(); i++)
{ 
    foo(i);
}

Где дорогостоящие вычисления без необходимости выполняются на каждой итерации цикла.

Да, это уменьшает размер.Дополнительная информация здесь

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top