我有一个调度函数,该函数在主线程中执行给定的lambda。为了这个问题,假设它看起来如下:
void dispatch(const std::function<void()>& fn) {
fn();
}
我需要在不中断主线程的情况下在新线程中加载新对象。因此,我执行以下操作:1)启动一个新线程并在该线程内创建一个新的唯一指针,2)调用dispatch
并传播它所属的新唯一指针。
std::unique_ptr<std::string> foo; // nullptr
// do the loading in a new thread:
std::thread t([&](){
// in the new thread, load new value "Blah" and store it temporarily
auto bar = std::make_unique<std::string>("Blah");
dispatch([bar2 = std::move(bar), &foo]() mutable {
foo = std::move(bar2); // propagate the loaded value to foo
});
});
t.join(); // for the sake of this example
std::cout << "foo = " << *foo << std::endl; // this should say: foo = Blah
在线运行示例:http : //cpp.sh/5zjvm
此代码不编译,因为在内部拉姆达dispatch
就是mutable
,因此不适合dispatch(const std::function<void()>& fn)
其需要const&
。
但是,lambda必须是mutable
因为它需要调用std::move
唯一的指针。
例如,可以通过更改dispatch
为以下代码来修复此代码:
template <typename Fn>
void dispatch(Fn fn) {
fn();
}
不幸的是,该dispatch
函数是库的API,我无法对其进行更改。
有没有摆脱唯一指针的方法来解决这个问题?
不,那不是你的问题。
您的问题是您的lambda无法复制,因为它具有按值捕获的唯一ptr。
std::function<Sig>
类型擦除到
调用 Sig
破坏
复制(有时移动)
退回原始类型
您的lambda无法复制,因此无法存储在中std::function
。
惰性编码器的解决方案是:
dispatch([bar2 = std::make_shared<decltype(bar)>(std::move(bar)), &foo]() mutable {
foo = std::move(*bar2);
});
我们将不可复制的状态推到shared_ptr
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句