I can only guess, but I would guess it is because it was added to C++ while rvalue references and forwarding references where being added to the language.
So some parts of its API got forwarding references, and some did not.
There is one minor advantage: if the copy constructor of F
could throw while the move cannot, std::function( F )
can be guaranteed not to throw, while std::function( F const& )
cannot be. The difference is that the copy would be done outside the constructor in the template<class F> function(F)
case, but inside the constructor in the template<class F> function(F&&)
case when passed a non-rvalue.
This is not a compelling reason.
It would also make it marginally easier to specify the SFINAE behavior of function(F)
, but that wasn't formalized until long after C++11, so that cannot be the reason.
The cost to template<class F>function(F)
is low -- one move of F
over the perfect forwarding version -- so it probably hasn't been high on anyone's priority list to change (especially because it causes a subtle change in the "could throw" tests of function(F)
, and hence could actually in theory cause some strange code to break).