加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 05:34:31 所属栏目:百科 来源:网络整理
导读:问题 我有一些C函数void f(),R g(T a),S h(U a,V b)等等.我想编写一个模板函数,它接受f,g,h等作为模板参数,并调用该函数. 我想要这样的东西: templateMagicStuff,WrappedFunctionReturnType wrapper(MagicallyCorrectParams... params){ extra_processing()
问题

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读