4

我有一种情况,我有一个 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;
}

提前致谢。

4

2 回答 2

5

您看到的问题是this指针被捕获到 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;
};

IDEOne的示例

于 2012-08-02T13:23:14.757 回答
3

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

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;
};
于 2012-08-02T13:21:47.700 回答