[英]Wrap a function pointer in C++ with variadic template
我有许多C ++函数void f()
, R g(T a)
, S h(U a, V b)
等等。 我想写一个模板函数,接受f
, g
, h
等作为模板参数并调用该函数。
即我想要这样的东西:
template<MagicStuff, WrappedFunction>
ReturnType wrapper(MagicallyCorrectParams... params)
{
extra_processing(); // Extra stuff that the wrapper adds
return WrappedFunction(params);
}
...
wrapper<f>(); // calls f
wrapper<g>(T()); // calls g
wrapper<h>(U(), V()); // calls h
template<typename ReturnType, typename Args...>
ReturnType wrapper(ReturnType (*wrappee)(Args...), Args... args)
{
extra_processing();
return wrappee(args...);
}
...
wrapper(f); // calls f OK
wrapper(g, T()); // calls g OK
wrapper(h, U(), V()); // calls h OK
这有效但不能令人满意,因为在我的情况下,我希望函数指针绑定到模板实例。 函数指针在编译时是静态可确定的,在我的用例中不希望在运行时将其作为参数传递。
template<
typename ReturnType, typename Args...,
ReturnType (*FuncPtr)(Args...)
>
wrapper(Args... args)
{
extra_processing();
return FuncPtr(args...);
}
...
wrapper<void, f>(); // calls f
wrapper<R, T, g>(T()); // calls g
wrapper<S, U, V, h>(U(), V()); // calls h
这有效但不令人满意,因为它很冗长。 返回类型和参数类型可以从函数指针本身推导出来。 什么是完美的模板规范,所以我可以做如上所述的wrapper<g>(T())
。
谢谢大家的帮助!
template<typename Fn, Fn fn, typename... Args>
typename std::result_of<Fn(Args...)>::type
wrapper(Args&&... args) {
return fn(std::forward<Args>(args)...);
}
#define WRAPPER(FUNC) wrapper<decltype(&FUNC), &FUNC>
//用法:
int min(int a, int b){
return (a<b)?a:b;
}
#include<iostream>
#include<cstdlib>
int main(){
std::cout<<WRAPPER(min)(10, 20)<<'\n';
std::cout<<WRAPPER(rand)()<<'\n';
}
或者,为了获得可能性相当低,但语法更短:
#define WRAPPER(FUNC, ...) wrapper<decltype(&FUNC), &FUNC>(__VA_ARGS__)
//用法:
int main(){
sdt::cout<<WRAPPER(min, 10, 20)<<'\n';
std::cout<<WRAPPER(rand)<<'\n';
}
这是迄今为止我能做到的最好的:
template<typename R, typename...A>
struct S<R(A...)>
{
typedef R(*F)(A...);
F f;
constexpr S(F _f) : f(_f) { }
inline R operator()(A... a)
{ return f(a...); }
};
#define wrapper(FUNC, ARGS...) (S<decltype(FUNC)>(FUNC))(ARGS)
int f(float g);
int main(void)
{
return wrapper(f, 3.0f);
}
可悲的是,我无法在MSVC下进行编译。
这里有一个副本,我记得它,但我找不到它......结论是不可能同时传递指针的类型及其值。
一些希望在于对隐式类型模板参数的建议,您可以在此处找到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.