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.
};
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.
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.
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 .
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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With