如何在类中存储lambda并将其捕获为参数

How can I store lambda with capture this in class as parameter?

本文关键字:参数 lambda 存储      更新时间:2023-10-16

我在存储lambda表达式时遇到问题,并在类中捕获"this"指针作为参数。我做了这样的typedef:

typedef void(*func)();

下面的代码运行良好。

#include <iostream>
using namespace std;
typedef void(*func)();
class A {
public:
    func f;
};
class B {
public:
    A *a;
    B() {
        a = new A();
        a->f = [](){
            printf("Hello!");
        };
    }
};
int main() {
    B *b = new B();
    b->a->f();
    return 0;
}

目前还没有捕获,但当我想在lambda中捕获"this"指针时,它会抛出一个错误。如何使用捕获进行typedef?我想做这样的事情:

#include <iostream>
using namespace std;
typedef void(*func)();
class A {
public:
    func f;
};
class B {
public:
    A *a;
    B() {
        a = new A();
        //There is a problem with [this]
        a->f = [this](){
            //Method from class B using "this" pointer
            this->p();
        };
    }
    void p() {
        printf("Hello!");
    }
};
int main() {
    B *b = new B();
    b->a->f();
    return 0;
}

我做错了什么?请解释一下。谢谢

不可能从带捕获的lambda转换为函数指针,因为带捕获的lambda包含的信息比函数指针更多(它不仅包含函数的地址,还包含已捕获的变量)。

typedef void(*func)();更改为typedef std::function<void()> func;以获得能够容纳任何可复制函数类型的内容。

正如Angew上面所说,您应该使用std::function类模板,而不仅仅是函数指针。你的代码会变成这个(从第二个例子复制)

#include <iostream>
#include <functional>
#include <memory>
using namespace std;

class A {
public:
    std::function<void> f;
};
class B {
public:
    shared_ptr<A> a;  // Better ownership
    B() 
     : a(new A())
    {
        // Now this should work
        a->f = [this](){
            //Method from class B using "this" pointer
            this->p();
        };
        // Note, you could just do this instead of a lambda:
        // a->f = bind(b::p, this);
    }
    void p() {
        printf("Hello!");
    }
};
int main() {
    B *b = new B();
    b->a->f();
    return 0;
}

除了正确的可调用对象外,我还通过智能指针添加了A的自动清理,并添加了代码来向您展示如何使用std::bind进行清理。