How to use a general function pointer as a template parameter?

16,447

Solution 1

A normal template argument can refer to a function.

#include <iostream>

template <class ArgT, class RetT, class F>
struct A {
    F f;
public:
    A(F f) : f(f) {}

    RetT operator()(ArgT arg) { return f(arg); }
};

int unchanged(int i) { return i; }

int main(){
    A < int, int, int(*)(int)> t{ unchanged };

    for (int i = 0; i < 10; i++)
        std::cout << t(i) << "\n";
}

There's nothing restricting the template argument to a function though -- you could just as easily use some class that overloads operator(), and invoke that instead (and, in fact, that's often preferable).

Solution 2

I would recommend to use std::function<> if you can use C++11 or boost::function<> if you cannot:

template<class ArgumentT, class ReturnT > struct A { 
    typedef std::function< ReturnT( ArgumentT ) > Function;
    void foobar( Function f ) { ReturnT ret = f( arg ); }
};

In this case you can pass function pointer, functor, lambda, or use std::bind or boost::bind with almost any function which signature does not match. I am not sure you need template in this case, you can use std::function directly, but that depends on your code.

Share:
16,447
user1899020
Author by

user1899020

Updated on June 11, 2022

Comments

  • user1899020
    user1899020 almost 2 years

    Is it possible to use a general function pointer as a template parameter? The function pointer template can accept free functions, member functions, and lambda functions. For simplicity, assuming the functions has only one argument, like

    template<class ArgumentT, class ReturnT, function* f>
    struct A
    {
       // f is used somewhere.
    };
    
  • xaxxon
    xaxxon over 7 years
    There are many downsides to using std::function, however, so this is not blanket advice.