увеличить лямбда-головоломка - PullRequest
4 голосов
/ 25 ноября 2008

Кто-нибудь знает, почему

  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"

Дает: "0 1 2 3 4 5 6 7 8 9"

но

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

Дает: "1 2 3 4 5 6 7 8 9 10"

Ответы [ 3 ]

9 голосов
/ 25 ноября 2008

Оператор запятой оценивает слева направо, поэтому результат

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

- это ++ var (a), который вы будете хранить, используя версию преобразования.

  • for_each:

    _1 + = var (a) оценивается, обновляя вашу последовательность (через лямбду _1), затем ++ var (a) оценивается, но это не влияет на вашу последовательность.

  • преобразования:

    _1 + = var (a) оценивается, обновляя вашу последовательность (как и раньше), затем ++ var (a) оценивается, это также дает результат всего выражения, а затем используется для обновления вашей последовательности снова (через преобразование)

2 голосов
/ 25 ноября 2008

преобразование (test.begin (), test.end (), test.begin (), (-1 + = Var (а), ++ Var (а)));

Это будет переводить на

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

for each elem : elem = doit(elem);

Начиная с = 0 приведет к 1 при первом запуске. Мы увеличиваем 10 раз, так что мы получим 10 в последнем запуске.


for_each (test.begin (), test.end (), (_ 1 + = Var (а), ++ Var (а)));

Это переведет на

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

for each elem : doit(elem);

Начиная с = 0, мы получим 0 при первом запуске. Мы увеличиваем в 10 раз, но присваиваем его непосредственно перед увеличением. Таким образом, последнее число - 9.

Надеюсь, теперь с переводом к обычным функциям понятно, что эти двое делают.

2 голосов
/ 25 ноября 2008

По существу, в for_each вы предоставляете функцию с побочным эффектом, а в transform вы используете возвращаемое значение функции.

В вашем случае вы снова используете ту же функцию. Поскольку operator += имеет возвращаемое значение, именно оно используется в результате преобразования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...