将带有unique_ptr的可变 lambda 传递给 const&std::function



我有一个调度函数,它在主线程中执行给定的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中的内部lambda是mutable,因此不适合需要const&dispatch(const std::function<void()>& fn)

但是,lambda需要是mutable,因为它需要在唯一指针上调用std::move

例如,可以通过将dispatch更改为:来修复此代码

template <typename Fn>
void dispatch(Fn fn) {
fn();
}

遗憾的是,dispatch函数是库的API,我无法更改它

有没有办法在不去掉唯一指针的情况下解决这个问题?

不,这不是你的问题。

您的问题是无法复制您的lambda,因为它有一个由值捕获的唯一ptr

std::function<Sig>型擦除至

  1. 使用Sig调用

  2. 销毁

  3. 复制(有时移动(

  4. 退回到原始类型

您的lambda无法复制,因此无法存储在std::function中。

懒惰编码器的解决方案是:

dispatch([bar2 = std::make_shared<decltype(bar)>(std::move(bar)), &foo]() mutable {
foo = std::move(*bar2);
});

其中我们将不可复制状态推入CCD_ 13。

相关内容

最新更新