I lately tried to do something like this:
auto x = std::make_unique<int>(1);
auto l = [y = std::move(x)]() { return *y; };
std::function<void()> f(std::move(l)); //error, requires copy construction
And to my huge disappointment and confusion it threw a bunch of error messages in my face. As you already know, std::function
disallows construction from types that are not copy-constructible. Is there a specific reason why is it so? Or is it an overlook in the standard? What problems would construction from move-only types impose?
std::function
could take a move-only callable, but only by restricting itself to being move-only always. It uses type-erasure to store the object, so its static behavior must represent the lowest-common-denominator functionality that it requires of the objects it stores.
Here's the thing though: there are a lot of places in C++ and its standard library that expect that a callable shall be copyable. And by "lot", I mean the entirety of the standard algorithms library. Even the C++20 concept indirect_unary_predicate
requires copy_constructible
. Essentially, all algorithms are given the freedom to copy the given function at will; they even take those functions by value.
A move-only std::function
type could never be used with any such algorithm. And being move-only is the only way for std::function
to take move-only types.