views:

277

answers:

2

Why is callback called once only?

bool callback()
{
    static bool res = false;
    res = !res;
    return res;
}

int main(int argc, char* argv[])
{
    vector<int> x(10);

    bool result=false;
    for_each(x.begin(),x.end(),var(result)=var(result)||bind(callback));

    return 0;
}
+7  A: 

The || expression short circuits after the first time bind returns true.

The first time you evaluate

result = result || bind(...)  // result is false at this point

bind is called, because that's the only way to determine the value of false || bind(...). Because bind(...) returns true, result is set to true.

Every other time you say

result = result || bind(...)  // result is true at this point

... the bind(...) expression isn't evaluated, because it doesn't matter what it returns; the expression true || anything is always true, and the || expression short circuits.

One way to ensure that bind is always called would be to move it to the left side of the ||, or change the || to an &&, depending on what you are trying to accomplish with result.

Daniel LeCheminant
And that's because Boost.Lambda's operator|| is specially designed to be short-circuiting in conjunction with the delayed-execution ability of the functor object that bind() returns. An ordinary overloaded operator|| does NOT short-circuit.
Rob Kennedy
yeah, that's a nice feature of it. usually if you overload operator||, short circuit does not happen. boost lambda seems to take care of it.
Johannes Schaub - litb
+1  A: 

In your particular example, Boost.Lambda doesn't really gain you anything. Get rid of the lambda parts, and maybe you'll see more clearly what's going on:

for (int i = 0; i < 10; ++i)
  result = result || callback();

This still relies on you to know that the || operator is short-circuited, as Daniel explained.

Rob Kennedy