我有一种情况,我有一个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;
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
您看到的问题是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;
};
Run Code Online (Sandbox Code Playgroud)
IDEOne上的示例