Call to lambda is ambiguous despite explicitly stating the return type
Because the 2nd lambda expression returning bool
could convert to both std::function<void(int)>
and std::function<bool(int)>
implicitly.
std::function
has a converting constructor:
template< class F > function( F f );
This constructor does not participate in overload resolution unless f is Callable for argument types Args... and return type R. (since C++14)
As the definition of Callable,
The following expressions must be valid:
INVOKE<R>(f, std::declval<ArgTypes>()...)
where INVOKE(f, t1, t2, ..., tN) is defined as
static_cast<void>(INVOKE(f, t1, t2, ..., tN))
if R is possibly cv-qualifiedvoid
, otherwise INVOKE(f, t1, t2, ..., tN), implicitly converted to R
Note that the 2nd lambda returning bool
, for the std::function<void(int)>
, as shown above, static_cast<void>(INVOKE(f, t1, t2, ..., tN))
is a valid expression (the returned bool
is just converted to void
). Then it could also convert to std::function<void(int)>
implicitly and causes the ambiguity issue.
You can explicitly static_cast
the lambda to the proper type
using FunBoolRet = std::function<bool(int)>;
do_some(static_cast<FunBoolRet >([&](int in)
{
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
}));
Or store the lambda to the proper std::function<bool(int)>
type and pass to the function(if do_some(lmda)
should be called many times)
FunBoolRet lmda = [&](int in)
{
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
};
do_some(lmda); // pass the lambda
Or as @MaxLanghof suggested
simply construct std::function<bool(int)>
from lambda on the go
do_some(FunBoolRet{
[&](int in)
{
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
}
});