Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.
};
like image 684
user1899020 Avatar asked Sep 25 '13 14:09

user1899020


People also ask

How do you pass a pointer to a function as a parameter?

Pass-by-pointer means to pass a pointer argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the variable to which the pointer argument points. When you use pass-by-pointer, a copy of the pointer is passed to the function.

Can template type be a pointer?

A template has only one type, but a specialization is needed for pointer, reference, pointer to member, or function pointer types. The specialization itself is still a template on the type pointed to or referenced.

How do you use a pointer to a function?

You can use a trailing return type in the declaration or definition of a pointer to a function. For example: auto(*fp)()->int; In this example, fp is a pointer to a function that returns int .

Can we pass Nontype parameters to templates?

Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.


2 Answers

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

like image 157
Jerry Coffin Avatar answered Sep 21 '22 13:09

Jerry Coffin


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.

like image 32
Slava Avatar answered Sep 22 '22 13:09

Slava