Вот мой код, я хочу проверить закрытие в c++, как javascript. Почему компилятор передает это сообщение? "testLambda.cpp: В лямбда-функции: testLambda.cpp: 8: 11: ошибка: 'а не зафиксировано"
#include <iostream>
#include <functional>
std::function<bool(int)> returnLambda(int a){
auto b = 1;
auto c = 2;
return [&](int x)
{ return x*(b++)+c+a == 0;};
}
auto f = returnLambda(21);
int main(){
auto c = f(1);
auto b = f(1);
std::cout<<c<<b<<std::endl;
return 0;
}
Вам нужно указать свои захваты в квадратных скобках, поэтому лямбдам требуется, в первую очередь, квадратные скобки. Вы можете захватить их по ссылке:
[&a,&b,&c] (int x) ...
или по значению:
[a,b,c] (int x) ...
или смешать его:
[a,&b,c] (int x) ...
Или вы можете просто захватить все, что вы используете:
[&] (int x) ... // by reference
[=] (int x) ... // by value
Если вы решите захватить переменную по значению, но вам нужно ее изменить, вам необходимо сделать ее изменчивой:
[=] (int x) mutable ...
Бенджамин Линдли дал ответ об объявлении лямбда в C++.
Но технически говоря, вы не можете воспроизвести закрытие JavaScript, используя C++ lambdas.
В JS внешние переменные, используемые локальной функцией, защищены механизмом GC.
Но в C++, если вы фиксируете переменные по ссылке, вы можете легко попасть в ситуацию, когда ссылочные переменные будут уничтожены, и вы получите нарушение сегментации/нарушение прав доступа.
Это, например:
#include <iostream>
#include <functional>
std::function<bool(int)> returnLambda(int a){
auto b = 1;
auto c = 2;
return [&](int x)
{ return x*(b++)+c == 0;};
}
auto f = returnLambda(21);
int main(){
auto c = f(1);
auto b = f(1);
std::cout<<c<<b<<std::endl;
return 0;
}
будет сильно повреждаться, поскольку после возврата из returnLambda() его переменные a, b и c уничтожаются (их расположение стека используется чем-то другим) при вызове функции f().
[]
где вы помещаете переменные захвата.