Search code examples
c++c++11templatestemplate-argument-deductiontype-deduction

C++ can't derive template parameters for high-order functions


When I use have template function which accepts another function as a parameter, C++ can't derive template parameters. It's very annoying to specify them all the time. How can I define the following function such that I don't have to specify type parameters every time?

#include <functional>

template <typename S, typename T>
T apply(const S& source, const function<T (const S&)>& f) {
  return f(source);
}

template <typename S, class Functor, typename T>
T applyFun(const S& source, const Functor& f) {
  return f(source);
}

int main() {
  // Can't derive T. Why?
  apply(1, [](int x) { return x + 1; });
  // Compiles
  apply<int, int>(1, [](const int& x) { return x + 1; });
  // Can't derive T. Kind of expected.
  applyFun(1, [](int x) { return x + 1; });
}

It makes sense to me why it can't derive type parameter in the second function, but not in the first one (since x + 1 is int, so it should deduce that T = int).


Solution

  • A template parameter must appear in a function parameter type to be deductible. Moreover lambdas are not functions so, whatsoever the return type of a lambda cannot participate to template argument deduction.

    But in this case, there is no need to specify the return type. Return type deduction can do the job:

    template <typename S, class Functor>
    auto applyFun(const S& source, const Functor& f) {
      return f(source);
      }