views:

431

answers:

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

Does the termination condition part "stlVector.size()" take "stlVector.erase(...)" into consideration? In other word does stlVector.size() refresh for every loop iteration? I can't test it right now, so i posted a question here.

Thx in advance!

Best regards,

zhengtonic

+4  A: 

Yes it does!

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

Thus for every loop you'll have the test "i < stlVector.size ()" re-evaluate!

claferri
+4  A: 

Yes, the test is performed, with side effects, for each loop.

A for loop is merely a nice convention - a for loop is easily decomposed as a while loop:

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

Becomes:

int i = 0 ;

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

Yes it reduces the size. More information is here

Vinay
+5  A: 

Just to be clear, don't think of it in terms of the loop refreshing anything. Every time the condition is checked (at the start of each time through the loop), the size() method is called on the stlVector variable, and the current size of the vector is returned.

The erase() method reduces the size of the vector, so the next time size() is called, the returned value will be smaller.

KeithB
+2  A: 

Yes, it does, but don't do this! If you want to remove elements from a vector, do it inside another loop. You are deleting elements after the i index in this case: nothing guarantees that the stlVector[i+5] element exists. If you remove the i-th element from the vector, your count is broken because you can jump elements without checking them.

The most safe way of doing this is storing references for the elements on the stlVector you want to delete on another vector, and then iterate on this auxiliar vector doing stlVector.erase(auxVector[i]).

jfsantos
Actually, if you read it again: he's not erasing the i+5:th element.And I believe the check "if (i == 10)" (together with the loop condition) basically guarantees that element begin()+5 exists, no? Moreover, isn't using iterators kind-of superior to the auxiliary vector solution that you suggest?
Pukku
You are right about the element checking and the use of iterators. I thought this example was just "fantasy code" and only wanted to point to a common mistake (using an index to point to an element in a vector that was altered inside a loop).
jfsantos
+1  A: 

Also, to clarify a bit, since you asked if it's done this way "in VC++ 6".

The "continue condition" is re-evaluate on every loop in EVERY version of C, C++, C# and Java.

If any complier does not generate code which does that, it is broken, and must be avoided.

James Curran
VC++6 is already broken :)
Johannes Schaub - litb
Yeah, VC++6 is definitely broken. I can't say if it's broken in this particular way, but it certainly is broken in countless other ways.
jalf
I just thought... Maybe the OP actually knows all this and is just incredibly sarcastic? :) Maybe his next question will be, "Does 2+2==4 in VC++6?" :-P
j_random_hacker
Actually not sarcastic ... just cautious. VC++ 6 never seize to amaze me.
zhengtonic
+1  A: 

As others have said, yes the condition is re-evaluated each time through the loop. That's why a common performance optimization is:

int saveSize = someExpensiveComputation();

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

where the loop conditional is at all expensive to compute, instead of

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

Where the expensive computation is needlessly done each iteration through the loop.

PhysicalEd
that's not really going to make anything faster on a decent compiler. since size() is O(1) in std::vector (the standard says so). The call will get inlined and the location of the vector object doesn't change mid-loop. So you are trading one memory ref for another...
Evan Teran
If you test it out, you'll find the assembly generated is usually identical (or equivalent in functionality)
Evan Teran
yes, that's why I said "where the loop conditional is at all expensive to compute". I didn't want to totally rewrite his example to make my point.
PhysicalEd
I edited the example to clarify my point.
PhysicalEd
+2  A: 

I expect the code you provided is just "fantasy code" (as one commenter put it) to give a concrete example of the type of thing you're trying to do.

However just in case it's not: the loop you gave will skip over the 12th element (i.e. the element originally in stlVector[11]) because when examining stlVector[10] you delete an earlier element, causing all later elements to shunt forward one position, but you still increment i at the end of the loop. So the next iteration will look at stlVector[11] which is actually the element that was originally in stlVector[12]. To remedy this, you need to --i after the call to erase().

j_random_hacker
+2  A: 

Always reevaluate sure!