The parentheses, the parentheses (and the precedence of operators).
See bottom of
http://www.cplusplus.com/doc/tutorial/operators/
This contains two operators:
( pos = str.find(strToFind, pos) ) != string::npos
It is similar to:
( foo = bar ) != gaz
Equality has higher precedence than assignment, but the parentheses change the evaluation order. Thus, the assignment is evaluated first.
One has to evaluate both operands before one can evaluate binary operator (the boolean && and || operators are exceptions). In case of your assignment, the call
str.find( strToFind, pos )
is evaluated. It returns a temporary unnamed value.
Then that temporary value is assigned to
pos
.
Assignment operator does return a value too. That is why you can write:
1 2 3 4 5 6 7 8 9 10 11
|
a = 42;
b = a;
c = b;
// or
c = b = a = 42;
// which is actually
c = ( b = (a = 42) );
|
Therefore, these are equivalent:
1 2 3 4 5 6 7 8 9 10
|
foo = bar;
if ( foo != gaz ) ...
// and
if ( (foo = bar) != gaz ) ...
// and
if ( gaz != (foo = bar) ) ...
|
Thus, it is the return value of call to string::find that is compared with string::npos. The value just happens to be stored in pos too.
That alone could lead to infinite loop. That is why the loop's body contains
pos += strToFind.size();
. That ensures (unless strToFind is empty) that the next call to string::find will not return the same position.
One could be a little less confusing:
1 2 3 4 5 6
|
string::size_type from = 0;
string::size_type match = string::npos;
while ( string::npos != ( match = str.find( strToFind, from ) ) ) {
// code that uses the match
from = match + strToFind.size();
}
|