tags:

views:

668

answers:

3

Does anybody know why

  vector<int> test(10);
  int a=0;

  for_each(test.begin(),test.end(),(_1+=var(a),++var(a)));

  for_each(test.begin(),test.end(),(cout << _1 << " "));
  cout << "\n"

Gives : "0 1 2 3 4 5 6 7 8 9"

but

  transform(test.begin(),test.end(),test.begin(), (_1+=var(a),++var(a)));
  ...(as before)

Gives : "1 2 3 4 5 6 7 8 9 10"

?

+9  A: 

Comma operator evaluates left to right, so the result of the

_1+=var(a), ++var(a)

is ++var(a), which you'll store using the transform version.

  • for_each:

    _1 += var(a) is evaluated, updating your sequence (via the lambda _1), then ++var(a) is evaluated, but this has no effect on your sequence.

  • transform:

    _1+=var(a) is evaluated, updating your sequence (just like before), then ++var(a) is evaluated, this also gives the result of the whole expression, then that is used to update your sequence again (via the transform)

Pieter
Took me a couple of re-reads to get it, but thanks :-)
Chris Huang-Leaver
+2  A: 

Essentially, in the for_each you provide a function with a side-effect, while in the transform, your use the returnvalue of a function.

In your case, you reuse the same function. Since operator += happens to have a return value, this is the one used as a result of the transformation.

xtofl
That's right. for_each is supposed to be const isn't it?
Chris Huang-Leaver
+2  A: 

transform(test.begin(),test.end(),test.begin(), (_1+=var(a),++var(a)));

This will translate to

int doit(int & elem) {
    elem += a;
    return ++a;
}

for each elem : elem = doit(elem);

Starting with a=0 will result in 1 in the first run. We are incrementing a 10 times, so we will get 10 in the last run.


for_each(test.begin(),test.end(),(_1+=var(a),++var(a)));

This will translate to

void doit(int & elem) {
    elem += a;
    ++a;
}

for each elem : doit(elem);

Starting with a=0, we will get 0 in the first run. We increment a 10 times, but assign it just before incrementing. Thus the last number is 9.

I hope it's clear now with the translation to ordinary functions what those two do.

Johannes Schaub - litb