使用可变模板在C中包装一个函数指针

前端之家收集整理的这篇文章主要介绍了使用可变模板在C中包装一个函数指针前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题

我有一些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';
}

猜你在找的C&C++相关文章