简体   繁体   English

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

[英]Passing a mutable lambda with unique_ptr into a const& std::function

I have got a dispatch function which executes a given lambda in a main thread. 我有一个调度函数,它在主线程中执行给定的lambda。 For the sake of this question, suppose it looks like the following: 为了这个问题,假设它看起来如下:

void dispatch(const std::function<void()>& fn) {
    fn();
}

I need to load a new object in a new thread without interrupting the main thread. 我需要在新线程中加载一个新对象而不会中断主线程。 So I do the following: 1) start a new thread and create a new unique pointer inside the thread, 2) call dispatch and propagate the new unique pointer where it belongs. 所以我执行以下操作: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

Run example online: http://cpp.sh/5zjvm 在线运行示例: http//cpp.sh/5zjvm

This code does not compile because the inner lambda in dispatch is mutable and so does not fit into dispatch(const std::function<void()>& fn) which requires a const& . 此代码无法编译,因为dispatch的内部lambda是mutable ,因此不适合需要const& dispatch(const std::function<void()>& fn)

The lambda, however, needs to be mutable because it needs to call std::move on the unique pointers. 然而,lambda需要是mutable因为它需要在唯一指针上调用std::move

This code could be fixed for example by changing dispatch to: 可以修改此代码,例如将dispatch更改为:

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

Unfortunately, the dispatch function is an API of a library and I cannot change it. 不幸的是, dispatch功能是库的API,我不能改变它。

Is there a way out of this problem without getting rid of unique pointers? 如果没有摆脱独特的指针,有没有办法摆脱这个问题?

No, that isn't your problem. 不,那不是你的问题。

Your problem is that your lambda cannot be copied, as it has a unique ptr captured by value in it. 你的问题是你的lambda无法复制,因为它有一个由值中捕获的唯一ptr。

std::function<Sig> type erases down to std::function<Sig>类型删除到

  1. Invoke with Sig Sig调用

  2. Destroy 破坏

  3. Copy (and sometimes move) 复制(有时移动)

  4. Cast-back-to-original-type 铸造回至原来的型

Your lambda cannot be copied, so cannot be stored in a std::function . 您的lambda无法复制,因此无法存储在std::function

The lazy-coder's solution is: 懒惰编码器的解决方案是:

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

where we shove the non-copyable state into a shared_ptr . 我们将不可复制的状态推送到shared_ptr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM