Please consider the following example:
#include <iostream>
#include <future>
std::size_t calc_something(std::size_t lim_)
{
std::size_t result = lim_ * 10;
return result;
}
void calc_something(std::size_t lim_, std::promise<std::size_t> &promise_)
{
std::size_t result = lim_ * 10;
promise_.set_value(result);
}
void async_calc()
{
std::future<std::size_t> async_calc = std::async(calc_something, 5);
std::cout<< "async_calc = " << async_calc.get() <<std::endl;
}
I am still new to multi-threading, but why -on earth- can't std::async
pick the correct overload? The second overload uses a reference to an std::promise
object.
I've looked at this question here but it doesn't explain why. Also, I do not get an ambiguity error.
The error I get is:
error: no matching function for call to 'async' std::future<std::size_t> async_calc = std::async(calc_something, 5);
Overload resolution happens based on types of arguments specified at the call site. When you're calling std::async
, you're not calling calc_something
but passing a pointer to the function to std::async
. There are no calc_something
call arguments and no way to resolve which of the two overloads' address to pass to std::async
.
The compiler cannot use the subsequent arguments of std::async
to resolve the overload. From the compiler's perspective, all std::async
arguments are unrelated and nothing implies they will be used to invoke calc_something
. In fact, you can call std::async
with arguments of types different from those calc_something
accepts, and it will work because they will get converted when calc_something
is invoked.
In order to resolve this ambiguity, you must explicitly cast the pointer to calc_something
to the exact type of the function pointer, matching one of the overloads.
std::async((std::size_t (*)(std::size_t))calc_something, 5);