If the template parameter appears in the type of some parameter of the function and is located there in the so-called. deduced context , the corresponding template argument will be deduced by the compiler from the type of the corresponding function argument. It requires that:
- all deductions of such template arguments (in each parameter of the function) were successful, and
- all deductions of the same patterned argument gave the same result
That is, here is an example
template <typename T> struct S { S(T) {} }; template <typename T> void foo(T t, S<T> s) {} int main() { foo(5, 5); }
will not compile because deduction of the template argument T from the type of the second argument of the function fails. The fact that the template argument T successfully deduced from the type of the first argument of the function does not save the situation. In this example, T is in a deductible context in both the first and second parameters. This means that deduction must be performed through both parameters and must complete successfully in both (and must output the same T value). Otherwise, the code is incorrect.
It is possible to suppress this destructive behavior of the second parameter of the function if, in the declaration of this parameter, you intentionally place T in the non-deduced context. For example, if the type of the second parameter is described as a nested type of a foreign wrapper pattern
template <typename T> struct S { S(T) {} }; template <typename T> struct W { using S = ::S<T>; }; template <typename T> void bar(T t, typename W<T>::S s) {} int main() { bar(5, 5); }
In this variant, the second argument of the function is excluded from the deduction process T and the deduction T is performed only on the basis of the first argument (and is successful).
Your example suffers from the same problem. That is, in your example, a working “crutch” might look like
template <typename T> struct W { using F = std::function<void(T)>; }; template <typename T> void invoke(typename W<T>::F f, T val) { f(val); } int main() { auto printer = [](int x){ std::cout << x; }; ::invoke(printer, 42); }
It may well be that I am missing the already prepared standard tool for solving the same problem in the same way.
anonymous_classtype being transferred it is not possible to display the template parameterTIt is not clear why you need this function if there isstd::invoke. - VTT