Lambda 表达式闭包函数不起作用

Lambda Expression closure function not working

本文关键字:不起作用 函数 闭包 表达式 Lambda      更新时间:2023-10-16

我想通过编译器确认lambda表达式和转换的闭包,并尝试编写以下内容:

//this example demonstrate lambda function in c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Sum
{
    int mySum;
    Sum(){}
    Sum(int s):mySum(s){}
    void operator()(int x){
        mySum += x;
    }
};
int main(int argc, char const *argv[])
{
    vector<int> v { 3, 4, 2, 1, 56, 2, 4, 65, 2, 9, 8, 5, 7 };
     auto sum = 0;
     //for_each(begin(v), end(v), [&mySum = sum](int x){ mySum += x;});
     for_each(begin(v), end(v), Sum());
     cout << sum << endl;
    return 0;
}

但是上面的 lambda 闭包不起作用。如果我删除默认构造函数,那么编译器会给出错误,如果我有这个,那么结果仍然是 0。

出了什么问题?

谢谢

更干净的是:

vector<int> v { 3, 4, 2, 1, 56, 2, 4, 65, 2, 9, 8, 5, 7 };
auto sum = for_each(begin(v), end(v), Sum()).mySum;
cout << sum << endl;

根据op的评论:

需要哪些更改才能通过函子获得与 由 lambda 表达式提供?

lambda 的等效代码为:

struct Sum
{
    int *mySum;
    Sum(){}
    Sum(int *s):mySum(s){}
    void operator()(int x){
        *mySum += x;
    }
};
int main(int argc, char const *argv[])
{
    vector<int> v { 3, 4, 2, 1, 56, 2, 4, 65, 2, 9, 8, 5, 7 };
     auto sum = 0;
     for_each(begin(v), end(v), Sum(&sum));
     cout << sum << endl;
    return 0;
}

您正在创建一个临时的 Sum 对象,将其传递给for_each并将其丢弃。 同时,不会修改名为 sum 的不相关的 int 变量。 此外,std::for_each 采用的 UnaryFunction 是按值计算的,因此它修改的 Sum 对象无论如何都是临时的。

lambda 将闭包变量捕获为成员,如果将它们指定为引用,则无论 lambda 本身是否是副本,它们都会引用外部作用域中可见的内容。 你可以像这样模拟lambda的作用:

//this example demonstrate lambda function in c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Sum
{
    int mySum;
    Sum(){}
    Sum(int s):mySum(s){}
    void operator()(int x){
        mySum += x;
    }
};
// Incorporates a reference to a UnaryFunction so it can be passed by
// reference.
template <class A, class T>
struct LambdaWrapper {
    LambdaWrapper(T &t) :t(t) { }
    void operator () (A a) { return t(a); }
    T &t;
};
int main(int argc, char const *argv[])
{
    vector<int> v { 3, 4, 2, 1, 56, 2, 4, 65, 2, 9, 8, 5, 7 };
     auto sum = Sum(0);
     //for_each(begin(v), end(v), [&mySum = sum](int x){ mySum += x;});
     //for_each(begin(v), end(v), LambdaWrapper<int,Sum>(sum)); // <-- this would be fine
     for_each(begin(v), end(v), [&sum](int x) { sum(x) }); // <-- also fine
     cout << sum.mySum << endl;
    return 0;
}