I created a templated function of which I am trying to automatically deduce the template argument. MCVE(compile it):
template<class Value, class Allocator>
void foo(const std::vector<Value, Allocator>& v, const std::function<void(const Value&)>& f)
{
}
int main()
{
vector<int> v;
foo<int>(v, [](const int&){}); //okay
//foo(v, [](const int&){}); //not okay
return 0;
}
I first thought the Allocator could not be deduced but that does not seem to solve it. My next guess is it has something to do with the lambda to std::function but no idea on further steps there. Anybody got any clues about what I need to do to make this deducible?
Ps: I know "const int&" could become "int" but in the real code there is a non scalar data type there.
Template argument deduction happens before implicit conversion of Lambda to std::fucntion
.
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
Meaning type deduction of the template parameter Value
on the 2nd function argument f
fails because the implicit conversion from lambda to std::function
are not considered.
As you showed you can specify template arguments explicitly (to bypass the template argument deduction). Or you can exclude the 2nd argument from deduction by using std::type_identity
to declare it as non deduced context.
The nested-name-specifier (everything to the left of the scope resolution operator
::
) of a type that was specified using a qualified-id:
e.g.
template<class Value, class Allocator>
void foo(const std::vector<Value, Allocator>& v, const std::function<void(const std::type_identity_t<Value>&)>& f)
{
}
LIVE
PS: std::type_identity
is supported from C++20; if the compiler you're using doesn't support it it's not hard to make one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With