即使我通过移动语义传递给lambda捕获,但它仍然尝试使用复制构造函数构造| C++

问题描述 投票:0回答:1
std::promise<int> promise{};
std::function<void()> newTask = [promise = std::move(promise), task = std::move(task)]() mutable
{

}

即使我通过 std::move(promise) 传递了valiable,编译器仍然尝试使用复制构造函数创建promise变量。

message : 'ThreadPool::push_task::<lambda_9f392fbd7670777c18dfd2efbf01c5ca>::<lambda_9f392fbd7670777c18dfd2efbf01c5ca>(const ThreadPool::push_task::<lambda_9f392fbd7670777c18dfd2efbf01c5ca> &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::promise<ReturnType>::promise(const std::promise<ReturnType> &)'
c++ c++17
1个回答
2
投票

如您所知,

std::function
不是 lambda,而是任何类型的可调用类型(包括 lambda)的通用容器。

为了使

std::function
易于使用,它是可复制的。

因此,我们放入

std::function
中的所有可调用对象都必须是可复制的,即使我们从未真正复制 lambda。

这种情况下的解决方案是不使用

std::function
,如下所示:

auto newTask = [promise = std::move(promise), task = std::move(task)]() mutable
{

}

使用此代码

auto
将推导出 lambda 的实际类型。对于 msvc,该类型内部拼写为
lambda_9f392fbd7670777c18dfd2efbf01c5ca
。请注意,您无法在代码中拼写该类型,只能为其指定别名。

在 C++23 中,如果需要多态包装器,只需使用

std::move_only_function

© www.soinside.com 2019 - 2024. All rights reserved.