c++c++14

Rationale behind making std::function require copy constructor


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?


Solution

  • 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.