将函数指针包装为C++;可变模板 问题 我有许多C++函数无效(),代码< >代码> R g(t a)< />代码>代码> s h(u a,v b)< /c>等等。我想编写一个模板函数,它接受f、g、h等作为模板参数并调用该函数

将函数指针包装为C++;可变模板 问题 我有许多C++函数无效(),代码< >代码> R g(t a)< />代码>代码> s h(u a,v b)< /c>等等。我想编写一个模板函数,它接受f、g、h等作为模板参数并调用该函数,c++,templates,c++11,function-pointers,variadic-templates,C++,Templates,C++11,Function Pointers,Variadic Templates,我想要这样的东西: template<MagicStuff, WrappedFunction> ReturnType wrapper(MagicallyCorrectParams... params) { extra_processing(); // Extra stuff that the wrapper adds return WrappedFunction(params); } ... wrapper<f>(); // calls f wrapper

我想要这样的东西:

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
模板
ReturnType包装器(MagicallyCorrectParams…params)
{
extra_processing();//包装器添加的额外内容
返回WrappedFunction(参数);
}
...
包装器();//呼叫f
包装器(T());//呼叫g
包装器(U(),V());//叫h
以下是我迄今为止所尝试的: 解决方案1
模板
ReturnType包装(ReturnType(*wrappee)(Args…,Args…Args)
{
额外处理();
返回包装纸(args…);
}
...
包装(f);//呼叫f OK
包装器(g,T());//呼叫g OK
包装器(h,U(),V());//叫h OK
这是可行的,但并不令人满意,因为在我的例子中,我希望函数指针绑定到模板实例。函数指针在编译时是静态确定的,在我的用例中,不希望在运行时将其作为参数传递

解决方案2
模板<
typename返回类型,typename参数。。。,
返回类型(*FuncPtr)(参数…)
>
包装器(Args…Args)
{
额外处理();
返回函数(参数…);
}
...
包装器();//呼叫f
包装器(T());//呼叫g
包装器(U(),V());//叫h
这是可行的,但并不令人满意,因为它太冗长了。可以从函数指针本身推断返回类型和参数类型。最好是有一个模板规范,这样我就可以像上面提到的那样做
wrapper(T())


谢谢你的帮助

这是迄今为止我所能做的最好的:

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);
}
模板
结构
{
类型定义R(*F)(A…);
F;
constexpr S(F_F):F(_F){
内联R运算符()(A…A)
{返回f(a…;}
};
#定义包装器(FUNC,ARGS…(S(FUNC))(ARGS)
int f(浮点数g);
内部主(空)
{
返回包装器(f,3.0f);
}
遗憾的是,我不能让它在MSVC下编译。

模板
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>
typename std::result\u of::type 包装器(Args&…Args){ 返回fn(标准::转发(参数)…); } #定义包装器(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';
}
int main(){
    sdt::cout<<WRAPPER(min, 10, 20)<<'\n';
    std::cout<<WRAPPER(rand)<<'\n';
}
intmin(inta,intb){

return(a这里的某个地方有一个副本,我记得它,但我找不到它…其结论是不可能同时传递指针的类型和值


一些希望在于对隐式类型模板参数的建议,您可以找到。

那么
std::function
呢?@quantdev,我试图避免使用
std::function
来解决这个问题。如果可能的话,我希望我的包装器实例化一个地址在编译时可以确定的函数。您可以d也只需要做
wrapper()
。你需要像
template struct Value;
和“推断”
T
。据我所知,这目前是不可能的,尽管关于某种
auto T
的建议不断出现。为了响应@KerrekSB,我认为可以编写一个用作
wrapper()的包装器;
,但不能用作
包装器()
ARGS…
语法是GCC扩展,请使用
..
而不是
ARGS…
\uuuu____________________________
而不是
ARGS。我建议的解决方案取决于标准。另外,它无论如何都不会在GCC下编译-第2行导致
错误:“S”不是类模板(注释
后消失;第4行和第7行导致
错误:函数返回函数
,我不知道如何修复它。如果您:添加
S
类模板声明(您的代码仅定义其专门化),请删除
constepr
(MS VC尚不支持),将主体添加到
f
函数中(以避免链接器错误)。其他更改没有那么重要。如果您愿意,完美转发
args…
。和
std::result\u的
decltype
,并手动取消引用
fn
,以防它不是函数指针(相对无意义)@Yakk我不能使用perfect forward,它会导致错误,我已经问了一个问题。@GingerPlusPlus谢谢,我想这可能是我们能做的最好的了。我可能会接受它,但我有几个问题:(1)在MSVC下编译它有没有运气?(2)不管怎样,它在用什么编译器?我在g++下测试了它,现在我将在下检查它MSVC@0xbe5077ed请给我错误信息/告诉我什么不起作用。
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';
}