C++函数调用包装器,函数作为模板参数

Eri*_*ric 9 c++ templates variadic-functions variadic-templates

我正在尝试创建一个通用的包装器函数,它将函数作为模板参数,并使用与该函数相同的参数作为其参数.例如:

template <typename F, F func>
/* return type of F */ wrapper(Ts... Args /* not sure how to get Ts*/)
{
    // do stuff
    auto ret = F(std::forward<Ts>(args)...);
    // do some other stuff
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

解决方案需要可以转换为具有相同类型的函数指针,func以便我可以将其传递给C api.换句话说,解决方案需要是一个函数而不是一个函数对象.最重要的是,我需要能够在包装函数中完成工作.

如果内联评论不清楚,我希望能够做如下的事情:

struct c_api_interface {
    int (*func_a)(int, int);
    int (*func_b)(char, char, char);
};

int foo(int a, int b)
{
    return a + b;
}

int bar(char a, char b, char c)
{
    return a + b * c;
}

c_api_interface my_interface;
my_interface.func_a = wrapper<foo>;
my_interface.func_b = wrapper<bar>;
Run Code Online (Sandbox Code Playgroud)

我找了相关的帖子并找到了这些,但没有一个是我想要做的.这些帖子大多涉及功能对象.我正在努力做甚么可能吗?

函数作为模板参数传递

函数包装器通过(函数对象)类(可变参数)模板

如何将函数指针和函数对象包装在通用代码中?

如何在可变参数模板类中获取函数指针的参数类型?

具有任何参数列表的函数的泛型函子

C++ Functors - 及其用途

为了回应前两个回复,我编辑了这个问题,以明确我需要能够在包装函数中工作(即在调用包装函数之前和之后修改一些全局状态)

T.C*_*.C. 8

template<class F, F f> struct wrapper_impl;
template<class R, class... Args, R(*f)(Args...)>
struct wrapper_impl<R(*)(Args...), f> {
    static R wrap(Args... args) {
        // stuff
        return f(args...);
    }
};

template<class F, F f>
constexpr auto wrapper = wrapper_impl<F, f>::wrap;
Run Code Online (Sandbox Code Playgroud)

用作wrapper<decltype(&foo), foo>.


Vol*_*erK 5

#include <utility>
#include <iostream>

struct c_api_interface { int (*func_a)(int, int); int (*func_b)(char, char, char); };
int foo(int a, int b) { return a + b; }
int bar(char a, char b, char c) { return a + b * c; }


template<typename Fn, Fn fn, typename... Args>
typename std::result_of<Fn(Args...)>::type
wrapper(Args... args) {
   std::cout << "and ....it's a wrap ";
   return fn(std::forward<Args>(args)...);
}
#define WRAPIT(FUNC) wrapper<decltype(&FUNC), &FUNC>

int main() {
  c_api_interface my_interface;
  my_interface.func_a = WRAPIT(foo);
  my_interface.func_b = WRAPIT(bar);

  std:: cout << my_interface.func_a(1,1) << std::endl;
  std:: cout << my_interface.func_b('a','b', 1) << std::endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

看到http://rextester.com/ZZD18334

  • 如果函数重载,则此方法将无法通过“WRAIT”宏起作用。 (2认同)