我有一个程序,我无法使用标准std::async
和线程机制。相反,我必须像这样编写程序:
void processor( int argument, std::function<void(int)> callback ) {
int blub = 0;
std::shared_ptr<object> objptr = getObject();
// Function is called later.
// All the internal references are bound here!
auto func = [=, &blub]() {
// !This will fail since blub is accessed by reference!
blub *= 2;
// Since objptr is copied by value it works.
// objptr holds the value of getObject().
objptr->addSomething(blub);
// Finally we need to call another callback to return a value
callback(blub);
};
objptr = getAnotherObject();
// Puts func onto a queue and returns immediately.
// func is executed later.
startProcessing(func);
}
我现在想知道我是做得对还是使用lambdas作为异步回调的最佳方法是什么。
编辑:在代码注释中添加了预期的行为。
有关blub
的问题的可能解决方案,请参阅答案/评论。
答案 0 :(得分:4)
函数对象将包含对局部变量blub
的引用。 与语言中的所有其他情况一样,在函数结束后,这不会使局部变量生效。
所有其他捕获对象的副本将存储在函数对象中,因为它们是按值捕获的。这意味着它们没有问题。
如果您希望它在函数结束后生效,则无法将其生命周期与函数联系起来:您需要动态存储持续时间。 std::unique_ptr
可以用来处理这样一个对象的清理,但它有点烦人,因为你不能“移动”捕获到一个lambda:S
auto blub = make_unique<int>(0); // [1]
std::shared_ptr<object> objptr = getObject();
// use std::bind to store the unique_ptr with the lambda
auto func = std::bind([=](std::unique_ptr<int>& blub) {
*blub *= 2;
objptr->addSomething(*blub);
callback(*blub);
}, std::move(blub)); // move the unique_ptr into the function object
objptr = getAnotherObject();
// func is not copiable because it holds a unique_ptr
startProcessing(std::move(func)); // move it
作为补充说明,旧的已弃用的std::auto_ptr
在这里实际上可以正常工作,因为如果lambda按值捕获它,它会被复制,其奇怪的复制语义正是所需要的。
<子> 1。有关make_unique
。