2

I want to write an 'evaluation' function that takes as input a function of unspecified return type that takes an integer, and an integer to call that function with.

What I've come up with is the following:

#include <functional>
template<typename T>
T eval(function<T(int)> f, int x) {
    return f(x);
}

Let's say I have an auto func = [] (int x) -> long { return (long)x * x; } which I want to evaluate using the above function. The way I used template functions before was to simply call it as I would any other function and let the compiler deduce the type.

However, this doesn't work with this eval function. eval<long>(func, 5) compiles and works fine, however eval(func, 5) does not:

Aufgaben10.5.cpp:23:25: error: no matching function for call to 'eval(main()::__lambda0&, int)'
     cout << eval(func, 5) << endl;
                         ^
Aufgaben10.5.cpp:23:25: note: candidate is:
Aufgaben10.5.cpp:8:3: note: template<class T> T eval(std::function<T(int)>, int)
 T eval(function<T(int)> f, int x) {
   ^
Aufgaben10.5.cpp:8:3: note:   template argument deduction/substitution failed:
Aufgaben10.5.cpp:23:25: note:   'main()::__lambda0' is not derived from 'std::function<T(int)>'
     cout << eval(func, 5) << endl;

Is there a way to write a template function that has the same return type as the lambda function without explicitly passing the type to the template, so that I can simply call eval(func, 5)?

David Südholt
  • 143
  • 1
  • 1
  • 8

1 Answers1

8

Why not use decltype?

template<typename Function>
auto eval(Function&& f, int x) -> decltype(std::forward<Function>(f)(x))
{
   return std::forward<Function>(f)(x);
}
ForEveR
  • 55,233
  • 2
  • 119
  • 133