Разница между захватом и передачей аргумента в лямбда-функциях
Я понимаю лямбда-функцию и ее цель в С++ 11. Но я не понимаю разницы между "Захват значения" и "Передача аргумента".
Для экземпляра..
#include <iostream>
#include <functional>
using namespace std;
int add(int a,int b){
return a+b;
}
int main(int argc, char** argv){
function <int(int,int)> cppstyle;
cppstyle = add;
auto l = [] (function <int(int,int)> f,int a, int b) {return f(a,b);};
cout << l(cppstyle,10,30) <<"\n";
}
Вывод кода выше того же кода, что и код ниже.
#include <iostream>
#include <functional>
using namespace std;
int add(int a,int b){
return a+b;
}
int main(int argc, char** argv){
function <int(int,int)> cppstyle;
cppstyle = add;
auto l = [cppstyle] (int a, int b) {return cppstyle(a,b);};
cout << l(10,30) <<"\n";
}
Захват значения аналогичен передаче значения в качестве аргумента? или захват имеет какое-то особое значение?
Ответы
Ответ 1
Различие между захваченным аргументом и передающим аргументом можно увидеть с аналогией. Рассмотрим следующий объект функции:
struct Capture {
int &i;
int const j;
public:
Capture(int &_i, int &_j) : i(_i), j(_j) {}
int operator()(int const a, int const b) {
i *= j;
return a * b;
}
};
В классе объектных объектов Capture
существуют две переменные-члены i
и j
. Там также перегружен operator()
, который принимает два входных аргумента. Теперь рассмотрим следующую лямбду:
int i, j;
[&i, j](int const a, int const b) {
i *= j;
return a * b;
};
Переменные-члены класса Capture
аналогичны лямбда-захвату (т.е. [&i, j]
), тогда как входные аргументы перегруженных operator()
a
и b
аналогичны входным аргументам a
и b
представленной выше лямбда.
То есть, если вы рассматриваете лямбду как объект функции, ее захват является состоянием объекта функции (т.е. его переменными-членами), тогда как его входные аргументы будут входными аргументами перегруженного operator()
.
Ответ 2
На более высоком уровне вы фиксируете данные, которые знаете сейчас, и передаете данные, которые у вас есть, пока вам не понадобится выполнить вызов.
Например, скажем, вы хотели добавить константу к каждому числу в векторе. Вы можете написать это как (осторожно: непроверено):
void Add(std::vector<int>& v, int i)
{
std::for_each(std::begin(v), std::end(v), [i](int& j){ j += i; });
}