将lambda传递给对象并在lambda内部修改该对象



我的代码看起来像这样:

struct LambdaContainer{ 
    std::function<void(void)> f;
    float x = 10;
}
struct MyClass{
    LambdaContainer c;
}
void someFunction(){
    MyClass ins;
    LambdaContainer cont;
    cont.f = [&cont](){
        // I want to modify 'x' of LambdaContainer that is inside MyClass
        cont.x = 10; // won't work because cont will be copy constructed
                     // and this cont might not exist anymore
    };
    ins.c = cont;
    aVectorSomewhere.push_back(ins);
}

是否有任何方法我可以捕获LambdaContainer 'cont'以这样一种方式,它指的是无论从哪里调用lambda ?(顺便说一下,我没有使用指针)

谢谢你这么好的回答:)我想我现在可以让它工作了

不捕获cont,而是将其传递给存储的lambda:

class LambdaContainer
{ 
private:
    std::function<void(LambdaContainer&)> f;
public:
    float x = 10;
    void call_f()
    {
        f(*this);
    }
};
void someFunction()
{
    MyClass ins;
    LambdaContainer cont;
    cont.f = [](LambdaContainer& self)
    {    
        self.x = 10;
    };
    ins.c = cont;
    aVectorSomewhere.push_back(ins);
}

当您想调用lambda时,只需从现有实例中执行LambdaContainer::call_f,或者根据您的设计添加从MyClass调用call_f的方法。

只是不要复制或分配不必要的东西,这样就可以了(更不用说更高效了):

struct LambdaContainer { 
    std::function<void(void)> f;
    float x = 10;
};   
struct MyClass {
    LambdaContainer c;
    MyClass(const MyClass&) = delete; // noncopyable
    MyClass& operator=(const MyClass&) = delete;
};
void someFunction(){
    MyClass ins;
    ins.c.f = [&ins](){
        ins.c.x = 10;
    };
    aVectorSomewhere.emplace_back(std::move(ins));
}

ins更改为动态分配并将MyClass*指针存储在矢量中(使用std::unique_ptr)。这样,lambda捕获的地址在对象的生命周期内不会改变,因为不涉及复制。

struct LambdaContainer {
    std::function<void(void)> f;
    float x = 10;
};
struct MyClass {
    LambdaContainer c;
};
std::vector<std::unique_ptr<MyClass>> aVectorSomewhere;
void someFunction() {
    std::unique_ptr<MyClass> ins(new MyClass);
    LambdaContainer &cont = ins->c;
    cont.f = [cont]() {
        cont.x = 10;
    };
    aVectorSomewhere.push_back(std::move(ins));
}
然后,稍后调用lambda:
aVectorSomewhere[index]->c.f();

最新更新