C++ 使用参数将仅可移动对象捕捉到lambda

C++ 使用参数将仅可移动对象捕捉到lambda,c++,c++11,lambda,C++,C++11,Lambda,基本上,我试图创建一个lambda来捕获一个只可移动的对象(例如unique_ptr),并将一些参数作为输入 我有一个由回调引发的昂贵资源,我需要将其移动到另一个线程进行处理。该对象仅可移动(并且不能更改),回调签名按值获取该对象(可以更改为右值引用)。以下是状态下问题的最小工作示例: void processor(std::function<void(int)> func) { auto thread = std::async(std::launch::async, fun

基本上,我试图创建一个lambda来捕获一个只可移动的对象(例如unique_ptr),并将一些参数作为输入

我有一个由回调引发的昂贵资源,我需要将其移动到另一个线程进行处理。该对象仅可移动(并且不能更改),回调签名按值获取该对象(可以更改为右值引用)。以下是状态下问题的最小工作示例:

void processor(std::function<void(int)> func)
{
    auto thread = std::async(std::launch::async, func, 2);
}

using ResourceType = std::unique_ptr<int>; //Example for moveable only type

void handler(ResourceType r)
{
    processor([r](int x) // error C2280: ...unique_ptr...: attempting to reference a deleted function
    {
        int usage_of_resource = *r + x;
        std::cout << usage_of_resource << std::endl;
    });
}
void处理器(std::function func)
{
自动线程=std::async(std::launch::async,func,2);
}
使用ResourceType=std::unique\u ptr//仅可移动类型的示例
无效处理程序(资源类型r)
{
处理器([r](int x)//错误C2280:…唯一\u ptr…:尝试引用已删除的函数
{
int usage_of_resource=*r+x;

std::cout相当于C++14的移动捕获

class MyFunctor
{
public:
    MyFunctor(ResourceType res) : res(std::move(res)) {}

    void operator() (int x) const {
        int usage_of_resource = *res + x;
        std::cout << usage_of_resource << std::endl;
    }
private:
    ResourceType res;
};
无论如何,您不能将其用于初始化
std::function
,因为它需要可复制的可调用

您可以在
std::shared_ptr
中包装或传输资源,以将其存储在
std::function
中,类似于:

void handler(std::unique_ptr<int> r)
{
    std::shared_ptr<int> sr = std::move(r);
    processor([sr](int x) {
        int usage_of_resource = *sr + x;
        std::cout << usage_of_resource << std::endl;
    });
}
void处理程序(std::unique\u ptr)
{
std::shared_ptr sr=std::move(r);
处理器([sr](整数x){
int usage_of_resource=*sr+x;

std::cout问题似乎在于,std::bind返回的对象如果包含
std::unique\u ptr
,则它们是不可移动的(或不可复制的)。我不确定原因。
std::function
应该是可复制的。正如我所写的“我尝试创建我自己的lambda(使用带操作符的结构())但是我没能解决同样的问题“,你如何传递
MyFunctor
(例如传递给
processor
)所以其他人会调用它?正如我所说,
std::function
需要可复制的可调用,所以你不能使用c++14移动捕获lambda,给定的等价物。你必须将你的资源包装在可复制的可调用中。
std::shared_ptr
可能会解决这个问题。使用
std::shared_ptr
是我最初的想法,但我没有我希望避免在该流程中进行堆分配,因此这对我来说不是一个最佳解决方案。当你说“将资源包装在一个可复制构造的可调用文件中”时,你不是指
MyFunctor
吗?如果是这样,那么我不知道如何创建一个。。。
void handler(ResourceType r)
{
    MyFunctor f{std::move(r)};
    f(42);
}
void handler(std::unique_ptr<int> r)
{
    std::shared_ptr<int> sr = std::move(r);
    processor([sr](int x) {
        int usage_of_resource = *sr + x;
        std::cout << usage_of_resource << std::endl;
    });
}