5

How to write a function calling any specified function (or function object) with specified arguments?

Here's what I tried:

#include <iostream>
#include <functional>

using namespace std;

template <typename RetType, typename... ArgTypes>
RetType q(function<RetType(ArgTypes...)> f, ArgTypes... args)
{
    return f(args...);
}

int h(int a, int b, int c) { return a + b + c; }

int main()
{
    auto r = q(h, 1, 2, 3);

    cout << "called, result = " << r;

    return 0;
}

The compiler says, that template argument deduction/substitution failed due to mismatched types 'std::function<_Res(_ArgTypes ...)>' and 'int (*)(int, int, int)'.

I'm not sure why template arguments can't be deduced in my code.

user3900460
  • 93
  • 1
  • 8

2 Answers2

3

Since it's a template anyway, you don't need std::function at all. Just do this:

template <class F, class... Arg>
auto q(F f, Arg... arg) -> decltype(f(arg...))
{
  return f(arg...);
}

Even better, use perfect forwarding:

template <class F, class... Arg>
auto q(F f, Arg&&... arg) -> decltype(f(std::forward<Arg>(arg)...))
{
  return f(std::forward<Arg>(arg)...);
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 1
    Since C++14, specifying trailing return type is unnecessary, thanks to return type deduction, so `auto q(F f, Arg&&... arg)` is enough. – user3900460 Jul 16 '15 at 09:39
0

You're probably taking a difficult path for a simple problem... You can just use closures taking no parameters for that...

#include <iostream>
#include <functional>

using namespace std;

int h(int a, int b, int c) { return a + b + c; }

int main()
{
    auto clsr = [](){ return h(1, 2, 3); };

    auto r = clsr();
    cout << "called, result = " << r;
    return 0;
}

with the advantage that the IDE will even suggest arguments for h when writing/editing this kind of code.

6502
  • 112,025
  • 15
  • 165
  • 265