在c ++ 11中重新绑定lambda ...是否可能?

时间:2012-08-02 13:03:51

标签: c++ lambda c++11

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

提前致谢。

2 个答案:

答案 0 :(得分: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

的示例

答案 1 :(得分: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;
};
相关问题