Forget about your case. as that is too complex for analysis.
Take this simple example:
template
struct X
{
X(T data) {}
};
template
void f(X x) {}
Now call f
as:
f(10);
Here you might be tempted to think that T
will be deduced to int
and therefore, the above function call should work. Well, that is not the case. To keep thing simple, imagine that there is another constructor which takes int
as:
template
struct X
{
X(T data) {}
X(int data) {} //another constructor
};
Now what T
should be deduced to, when I write f(10)
? Well, T
could any type.
Note that there could be many other such cases. Take this specialization, for instance:
template
struct X //specialized for pointers
{
X(int data) {};
};
Now what T
should be deduced to for the call f(10)
? Now it seems even harder.
It is therefore non-deducible context, which explains why your code doesn't work for std::function
which is an identical case — just looks complex at the surface. Note that lambdas are not of type std::function
— they're basically instances of compiler generated classes (i.e they're functors of different types than std::function
).