无法在std::function<>中传递std::unique_ptr
#include <functional>
#include <memory>
#include <string>
#include <iostream>
void foo(std::function<void()> f)
{
f();
}
int main()
{
std::unique_ptr<int> handle = std::make_unique<int>(5);
foo(
[h = std::move(handle)]() mutable
{
std::cout << *h << std::endl;
});
}
以下代码不会编译出错
C:Program Files (x86)Microsoft Visual Studio2019ProfessionalVCToolsMSVC14.28.29910includefunctional(914,58): 错误 C2280: 'main::<lambda_1aa523ba59bbecea5306bc1fd>1781bc1fd178c1fd178c1fd178c1fd1781bc1fd1781bc1fd1781bc1fd1781b >(const main::<lambda_1aa523ba59bbecea5306bc1fd178120f> &)':试图引用已删除的函数
- 为什么会发生?
- 有没有办法在 std::function<void()> 中传递 std::unique_ptr 而不通过引用传递它?
回答
这std::function要求函数对象是可复制构造的,因此您不能指望将 lamdba 移动到它。在初始化时,它尝试复制 lambda 等std::unique_ptr,它是此 lambda 的成员,但预计会失败。您可以做的是将您的 lambda 存储在一个变量中,并将其传递给接受这样const std::function&使用的函数std::ref:
void foo(const std::function<void()>& f); // function declaration
auto a = [h = std::move(handle)]() mutable
{
std::cout << *h << std::endl;
};
foo(std::ref(a));
这是一个具有更详细答案的相关问题:How to create an std::function from a move-capturing lambda expression?
- you don't have to change `foo`, however you do need to be careful about how it uses `f`, as after `foo` ends the reference inside copies of `f` will dangle
THE END
二维码