c++ – How can I pass a function template to another function?

Question:

How to write the test function correctly so that any of the f and g functions can be passed to it as an argument (or a template parameter – it does not matter), with the possibility of calling them with different argument types (int, char and long in the example).

http://ideone.com/1aZ8Zu

#include <iostream>

using namespace std;

template <typename T> auto f(T x) -> decltype(x*x)
{
  return x * x;
}

template <typename T> T g(T x)
{
  return x * x;
}

template <template <class> class F> void test(F f)
{
    auto a = f(32);
    auto b = f(' ');
    auto c = f(2000000000L);

    cout << a << ' ' << b << ' ' << c << endl;
}

int main()
{
    test(f);
    test(g);

    return 0;
}

This code doesn't compile with messages:

prog.cpp:15:47: error: variable or field 'test' declared void
 template <template <class> class F> void test(F f)
                                               ^
prog.cpp:15:49: error: missing template arguments before 'f'
 template <template <class> class F> void test(F f)
                                                 ^
prog.cpp: In function 'int main()':
prog.cpp:26:8: error: 'test' was not declared in this scope
  test(f);
        ^

Answer:

I can recommend in a certain sense a workaround, but in a certain sense – and a direct way. In C ++ 14 (and you have this tag clearly specified), lambdas can also be templates.

auto f = [](auto x){ cout << x << endl; return x*x; };

template<typename F> void test(F f)
{
    auto a = f(32);
    auto b = f(' ');
    auto c = f(2000000000ull);

    cout << a << ' ' << b << ' ' << c << endl;
}

int main()
{
    test(f);
    return 0;
}

f is called exactly as a template (different for different arguments).

Yes, this is not an absolutely strict and exact answer to the question asked, but – the template in the template is called 🙂

You can also use lambda as a level of indirection:

template <typename T> T g_(T x)
{
  return x * x * x;
}

auto g = [](auto x){ cout << typeid(x).name() << endl; return g_(x); };

template<typename F> void test(F f)
{
    auto a = f(32);
    auto b = f(' ');
    auto c = f(2000000000ull);
    cout << a << ' ' << b << ' ' << c << endl;
}

int main()
{
    test(g);

    return 0;
}

Example of ideone: http://ideone.com/kfUWtx

Scroll to Top