C++ 在c+中重新绑定lambda+;11... 可能吗?

C++ 在c+中重新绑定lambda+;11... 可能吗?,c++,lambda,c++11,C++,Lambda,C++11,我有一种情况,我有一个lambda作为成员变量,它是由某个函数调用创建的。问题是,它将此捕获作为其操作的一部分。稍后,我希望能够复制整个对象 然而,在复制的时候,我不知道lambda是如何创建的(它可以通过不同的代码路径在多个点中定义)。因此,对于在复制构造函数中放置什么,我有些不知所措。理想情况下,我希望将lambda的捕获“重新绑定”到创建的新“this” 这有可能吗 下面是一些示例代码: #include <iostream> #include <string> #

我有一种情况,我有一个lambda作为成员变量,它是由某个函数调用创建的。问题是,它将此捕获作为其操作的一部分。稍后,我希望能够复制整个对象

然而,在复制的时候,我不知道lambda是如何创建的(它可以通过不同的代码路径在多个点中定义)。因此,对于在复制构造函数中放置什么,我有些不知所措。理想情况下,我希望将lambda的捕获“重新绑定”到创建的新“this”

这有可能吗

下面是一些示例代码:

#include <iostream>
#include <string>
#include <functional>

class Foo
{
  public:

    Foo () = default;
    ~Foo () = default;

    void set (const std::string & v)
    {
        value = v;
    }

    void set ()
    {
        lambda = [&]()
        {
            return this->value;
        };
    }

    std::string get ()
    {
        return lambda();
    }


    std::string value;
    std::function <std::string (void)> lambda;
};

int main ()
{
    Foo foo;

    foo.set ();
    foo.set ("first");

    std::cerr << foo.get () << std::endl; // prints "first"

    foo.set ("captures change");

    std::cerr << foo.get () << std::endl; // prints "captures change"

    Foo foo2 (foo);
    foo2.set ("second");

    std::cerr << foo.get () << std::endl; // prints "captures change" (as desired)
    std::cerr << foo2.get () << std::endl; // prints "captures change" (I would want "second" here)

    return 0;
}
#包括
#包括
#包括
福班
{
公众:
Foo()=默认值;
~Foo()=默认值;
无效集(常数std::string&v)
{
值=v;
}
空集()
{
lambda=[&]()
{
返回此->值;
};
}
std::string get()
{
返回lambda();
}
std::字符串值;
std::函数lambda;
};
int main()
{
富富,;
foo.set();
foo.set(“第一”);

std::cerr我认为您不能修改闭包。如果您需要函数对另一个对象进行操作,则需要将指向该对象的指针作为参数传递给函数:

class Foo
{
  public:

    Foo () = default;
    ~Foo () = default;

    void set (const std::string & v)
    {
        value = v;
    }

    void set ()
    {
        lambda = [](Foo* t)
        {
            return t->value;
        };
    }

    std::string get ()
    {
        return lambda(this);
    }

    std::string value;
    std::function <std::string (Foo*)> lambda;
};
class-Foo
{
公众:
Foo()=默认值;
~Foo()=默认值;
无效集(常数std::string&v)
{
值=v;
}
空集()
{
λ=[](Foo*t)
{
返回t->value;
};
}
std::string get()
{
返回lambda(本);
}
std::字符串值;
std::函数lambda;
};

您看到的问题是,
指针被捕获到lambda中,但您现在正在从另一个对象执行函数的副本。它在您的示例中起作用,因为两个对象都存在,但它是一个悬空的指针,等待发生

最干净的方法是修改
std::function
和lambda以获取指向类的指针的参数,并使用传入的指针而不是捕获。根据lambda的内容,可以选择捕获值

class Foo
{
  public:

    Foo () = default;
    ~Foo () = default;

    void set (const std::string & v)
    {
        value = v;
    }

    void set ()
    {
        lambda = [](Foo* self)
        {
            return self->value;
        };
    }

    std::string get ()
    {
        return lambda(this);
    }


    std::string value;
    std::function <std::string (Foo*)> lambda;
};
class-Foo
{
公众:
Foo()=默认值;
~Foo()=默认值;
无效集(常数std::string&v)
{
值=v;
}
空集()
{
lambda=[](Foo*self)
{
返回自我->价值;
};
}
std::string get()
{
返回lambda(本);
}
std::字符串值;
std::函数lambda;
};

例如,在

中,您没有lambda成员变量,您有一个名为
lambda
@juaNchopanza的
std::function
数据成员,您是对的:D