This might look similar to "I cannot pass lambda as std::function", but I'm actually passing the std::function parameter by value, so that problem doesn't apply. I've defined the following function.
template<typename T>
std::vector<T> countSort(const std::vector<T> &v, std::function<int(T)> keyFunc, int n);
The second parameter is an std::function that maps T to int (passed by value).
When calling this, I wanted to use a lambda expression, as follows:
std::vector<int> v;
[...]
v = countSort(v, [](int x) { return x; }, 10);
But the template argument deduction fails, because "main()::<lambda(int)> is not derived from std::function<int(T)>". It does work if I specify the template argument, or if I introduce an intermediate variable of type std::function for the lambda expression:
std::function<int(int)> lambda = [](int x) { return x; };
v = countSort(v, lambda, 10);
Why can't I do the former? I'm giving the compiler the exact same information; if it is able to convert a value of type lambda<int> to std::function<int(int)> when assigning it to a variable, why can't it directly convert from lambda<int> to the parameter type, which is std::function<T(int)>—and taking into account that v is of type std::vector<int>, it should know that T is int? The whole reason I want to use a lambda expression is precisely that, it's an expression, so I should be able to write it inline in the function call argument list, without having to give it a name or assign it to a variable.