Reputation: 13575
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.
};
Upvotes: 7
Views: 16526
Reputation: 44288
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.
Upvotes: 2
Reputation: 14420
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.
Upvotes: 0
Reputation: 490693
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).
Upvotes: 9
Reputation: 27577
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
};
Upvotes: 0