问题
我有一些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
这是我迄今为止所尝试的:
解决方案1
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
这是有效的,但不能令人满意,因为在我的情况下,我想要绑定到模板实例的函数指针.函数指针在编译时可以静态地确定,在我的用例情况下,不必在运行时将其作为参数传递.
解决方案2
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
这是工作,但不满意,因为它是详细的.返回类型和参数类型可以从函数指针本身推导出来.什么是完美的是模板规范,所以我可以执行如上所述的包装器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'; }