如何解决通过const std :: function引用传递临时lambda应该失败,但似乎可以正常工作
这是我正在做的简化版本:
#include <iostream>
#include <functional>
class thing
{
public:
void register_fn(const std::function<void()> &fn)
{
m_fn = fn;
}
void run()
{
m_fn();
}
std::function<void()> m_fn;
};
int main() {
// Create a thing object
thing t;
// In a limited scope
{
// Local lambda
auto afn = []{std::cout << "hi\n";};
// Store the lamda by reference
t.register_fn(afn);
}
// Run the stored lambda (which should be destroyed - therefore dangling reference??)
t.run();
// Take a copy
thing t2 = t;
t2.run();
return 0;
}
看到它在这里运行:https://godbolt.org/z/6qW3ro
因此,我有一个存储通过引用传递的临时lambda的类。 lamda afn
的范围是有限的,因此一旦将其传递给寄存器函数,它将超出范围。然后,在此范围之外,我调用run
函数,该函数应运行对lambda的(悬挂)引用。
这一直有效,但是最近回头看我的代码,我对此表示怀疑。由于lambda是临时的(通过限制我的lambda对象afn
的范围来完成)-这应该行不通...我不太清楚为什么行之有效-除非运气好,这是不确定的行为?
或者...我在这里误解了什么? -因为这可能是最可能的解释!
解决方法
这主要是因为您复制了功能对象。在
Observables
您将void register_fn(const std::function<void()> &fn)
{
m_fn = fn;
}
分配给fn
进行复制,并且即使m_fn
是对本地Lambda的引用,进行复制也意味着fn
不会引用m_fn
,但将获得其中存储的功能fn
的副本。这意味着没有悬空的引用,并且您的代码具有明确定义的行为。
如果lambda通过引用捕获本地对象,则情况将有所不同,因为在您离开声明lambda的范围之后,该捕获将变得无效。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。