Подтвердить что ты не робот

С++ Lambdas: список списка захвата и список параметров

Согласно стандарту С++ 11, лямбда-выражения могут использовать переменные в охватывающей области, с помощью списка захвата, списка параметров или обоих.

Итак, рассмотрим две версии одного и того же кода.

1) С захватом

int x = 4;

cout << "With capture  : Factorial of " << x << " = " << [x]() // <= Capture
{
    int r = 1;
    for (int i = x; i > 1; i--) r = r * i;
    return r;
}() << endl;

2) С параметром

int x = 4;

cout << "With parameter: Factorial of " << x << " = " << [](int x) // <= Parameter
{
    int r = 1;
    for (int i = x; i > 1; i--) r = r * i;
    return r;
}(x) << endl;

Вывод:

With capture  : Factorial of 4 = 24
With parameter: Factorial of 4 = 24

Так как мы можем передавать параметры в lambdas в списке параметров (как и в случае любой функции С++), зачем нам нужен список захвата?

Может ли кто-нибудь показать мне случаи, когда список параметров не работает, и только список захвата делает?

4b9b3361

Ответ 1

Например, используя stl-алгоритмы:

std::vector<int> items;
int factor;
auto foundItem = std::find_if(items.begin(), items.end(), 
[&factor](int const& a) 
{ 
   return a * factor == 100; 
});

В этом случае вы вызываетесь в лямбда для каждого элемента в контейнере, и вы возвращаете, если значение, умноженное на захваченный коэффициент, равно 100. Код не имеет особого смысла, он просто показывает вам пример, в котором содержатся списки захвата и параметров.

Ответ 2

Дело в том, что с захватом вы можете сохранить состояние (как написанный вручную класс с помощью оператора()) в функционально подобном объекте. @dau_sama дает хороший ответ. Вот еще один пример:

#include <iostream>
using namespace std;

int main() {

  const auto addSome = [](double some){
    return [some](double val){ return some+val; } ;
  };

  const auto addFive = addSome(5);

  std::cout << addFive(2) << std::endl;
}