SungJinKang
SungJinKang

Reputation: 429

even though i passed to lambda capture through move semantic, but it still try construct with copy constructor | C++

std::promise<int> promise{};
std::function<void()> newTask = [promise = std::move(promise), task = std::move(task)]() mutable
{

}

even though i passed valiable through std::move(promise), compiler still try make promise variable with copy constructor.

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> &)'

Upvotes: 0

Views: 342

Answers (1)

Guillaume Racicot
Guillaume Racicot

Reputation: 41770

As you know, std::function is not a lambda, but a generic container for any kind of invocable type, including lambdas.

To make std::function easy to use, it is copyable.

Therefore, all invocable object we put inside a std::function must be copyable, even if we never actually copy the lambda.

The solution in this case would be to not use std::function, like this:

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

}

With this code auto will deduce the actual type of the lambda. For msvc, that type is internally spelled lambda_9f392fbd7670777c18dfd2efbf01c5ca. Note that you cannot spell that type in code, only alias to it.

In C++23, simply use std::move_only_function if a polymorphic wrapper is needed.

Upvotes: 3

Related Questions