The function std::async
is defined like so:
template< class Function, class... Args>
std::future<std::result_of_t<std::decay_t<Function>(std::decay_t<Args>...)>>
async( Function&& f, Args&&... args );
As we can see, it takes both arguments as rvalue-references, or more precisely, as "universal references" (rvalue references to the template argument types).
Passing a simple function pointer (e.g. std::async(myfunction)
) works, and I don't understand why.
My understanding is that you can bind an rvalue to a const lvalue reference - but not vice versa. You cannot bind an lvalue to an rvalue reference (without casting it to an rvalue using std::move
).
However - when calling std::async(myfunction)
, the std::async
template is instantiated with Function = <some_func_type>
, and so becomes std::async<some_func_type>(some_func_type&&)
. That is - it takes an rvalue reference. However, we pass it an lvalue.
Why does it work?