问题
I want to pass a function value as a template parameter to a function. Currently the best I managed to do is :
template< typename F, F f >
void pass()
{
...
}
...which is used:
pass< decltype(&func), &func >();
What I would really like is to have:
pass< &func >();
Is there any way to achieve this without macros? Basically to pass both the type and the value at the same time? The compiler obviously has all the information needed for that...
The solution must work with variable parameters and return types. The function value is used at compile time, so it cannot be passed as an argument.
C++11 solutions welcome.
Edit: use case - I'm generating bindings at compile-time, where I need to create a C++ function for each passed function. The use case of this code looks (simplified) more or less like this:
template < typename F, F f >
int function_wrapper( lua_State* L )
{
return dispatcher<typename return_type<F>::type>::call( L, 1, f );
}
void register_native_function( lua_Function f, const char* name )
{
// binding call using pure C function f
}
template < typename F, F f >
void register_function( const char* name )
{
register_native_function( function_wrapper< F, f >, name );
}
Please note that I need to create a compile-time function wrapper, so I need the pass function value at compile time. There are binding solutions that allow binding at runtime, but they always require boilerplate code compared to hand-written bindings. I'm aiming to achieve a hand-written performance here.
回答1:
I believe shortening this is currently impossible. A year ago, the C++ committee looked at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3601.html to fix this, and they encouraged the authors to pursue it further after C++14 was released.
回答2:
It's now possible in C++17 with template<auto>
:
template<auto Func>
struct FuncWrapper final
{
template<typename... Args>
auto operator()(Args &&... args) const
{
return Func(std::forward<Args>(args)...);
}
};
int add(int a, int b)
{
return a + b;
}
int main()
{
FuncWrapper<add> wrapper;
return wrapper(12, 34);
}
Demo: https://godbolt.org/g/B7W56t
You can use #ifdef __cpp_nontype_template_parameter_auto
to detect compiler support for this in your code.
回答3:
You need to make a typedef for whatever function type you want to pass as a pointer, like this:
typedef int (*MyFunctionType)(int);
template <typename FunctionTypedef, typename ReturnType, typename ParameterType>
ReturnType callFunction(FunctionTypedef functionPointer, ParameterType i)
{
static MyFunctionType myFunctionPointer = functionPointer;
return (*functionPointer)(i);
}
int myFunction(int i)
{
}
int main()
{
int i = 7;
MyFunctionType myFunctionPointer = myFunction;
return callFunction<MyFunctionType, int, int>(myFunctionPointer, i);
}
Edit: If you want to store these arbitrarily typed function pointers, then make a base class with a virtual "call function" function, and a templated derived class that implements this function.
来源:https://stackoverflow.com/questions/24185315/passing-any-function-as-template-parameter