gpt4 book ai didi

c++ - 使用参数将只能移动的对象捕获到 lambda

转载 作者:太空狗 更新时间:2023-10-29 21:34:52 24 4
gpt4 key购买 nike

基本上我正在尝试创建一个 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;
});
}

我试着按照这个问题和答案 ( How to capture a unique_ptr into a lambda expression? )但是,我不能使用 C++14,那里的建议答案甚至无法编译。这是我尝试过的:

std::function<void(int)> getAction(ResourceType p)
{
return std::bind([](ResourceType& r, int x)
{
int usage_of_resource = *r + x;
std::cout << usage_of_resource << std::endl;
}, std::move(p), std::placeholders::_1);
}
void handler(ResourceType r)
{
processor(getAction(std::move(r)));
}

g++: error: use of deleted function

msvc: error: attempting to reference a deleted function

我曾尝试创建自己的 lambda(使用带有 operator()struct),但我未能解决同样的问题。最终,作为一种解决方法,我创建了一个指向我的资源的新指针,并在调用处理器之前将其移动到那里,然后将其提取到我传递的 lambda 中。

这是仅在 C++14 中解决的 C++ 标准的真正问题吗?或者有没有办法以某种方式移动对象(当然最好是优雅的)?

编辑:

捕获底层资源可能会导致内存泄漏,因为处理器是一个固定大小的消息队列,当队列已满且有新元素到达时会丢弃第一个元素(出队)。因此,在捕获时间和使用时间之间,lambda 可以被丢弃,因此资源不会被释放。

最佳答案

相当于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;
};

并使用它:

void handler(ResourceType r)
{
MyFunctor f{std::move(r)};
f(42);
}

你不能用它来初始化 std::function 因为它需要 CopyConstructible 可调用。

您可以在 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;
});
}

关于c++ - 使用参数将只能移动的对象捕获到 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45067467/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com