7

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.
};
1
  • You can do that, but you will get different incompatible types for the different function type instantiations. That is, you cannot assign an A with a general function pointer to an A with a pointer to member function, even if ArgumentT and ReturnT are the same. Commented Sep 25, 2013 at 15:01

4 Answers 4

9

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).

Sign up to request clarification or add additional context in comments.

Comments

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.

1 Comment

There are many downsides to using std::function, however, so this is not blanket advice.
0

You're combining types and data, you want something more like:

template<class ArgumentT, class ReturnT, typename F*>
struct A {
    //use F* to refer to f somewhere
};

Comments

0

You can achieve something close with:

template<class ArgumentT, class ReturnT, class F, F f>
struct A;

template<class ArgumentT, class ReturnT, ReturnT (*f)()>
struct A<ArgumentT, ReturnT, ReturnT (*)(), f>
{
   // f is used somewhere.
};

template<class ArgumentT, class ReturnT, class C, ReturnT (C::*f)()>
struct A<ArgumentT, ReturnT, ReturnT (C::*)(), f>
{
   // f is used somewhere.
};

...but you can't take something like a std::function<ReturnT ()> as a non-type template parameter. The specialisation for function pointers will also accept non-capturing lambdas.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.