以函数作为模板参数的C++函数调用 Package

wydwbb8l  于 2022-12-24  发布在  其他
关注(0)|答案(7)|浏览(175)

我正在尝试创建一个通用的 Package 器函数,它将一个函数作为模板参数,并将与该函数相同的参数作为它的参数。

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;
}

解决方案需要转换为与func相同类型的函数指针,以便我可以将其传递给C API。换句话说,解决方案需要是函数而不是函数对象。最重要的是,我需要能够在 Package 器函数中工作
如果内联注解不清楚,我希望能够执行以下操作:

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>;

我找了相关的帖子,找到了这些,但是没有一个是我想做的。这些帖子大部分都是关于函数对象的。我想做的事情可能吗?
Function passed as template argument
Function wrapper via (function object) class (variadic) template
How does wrapping a function pointer and function object work in generic code?
How do I get the argument types of a function pointer in a variadic template class?
Generic functor for functions with any argument list
C++ Functors - and their uses
作为对前两个回答的回应,我编辑了这个问题,以明确我需要能够在 Package 器函数中进行工作(即在调用 Package 函数之前和之后修改一些全局状态)

rseugnpd

rseugnpd1#

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;

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

txu3uszq

txu3uszq2#

#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;
}

参见http://rextester.com/ZZD18334

dba5bblo

dba5bblo3#

你可以尝试类似的东西(丑陋,但工作)

#include <iostream>
#include <functional>

struct wrapper_ctx
{
  wrapper_ctx ()
  {
    std::cout << "Before" << std::endl;
  }
  ~wrapper_ctx ()
  {
    std::cout << "after" << std::endl;
  }
};

template <typename F, typename... Args>
auto executor (F&& f, Args&&... args) -> typename std::result_of<F(Args...)>::type
{
  wrapper_ctx ctx;
  return std::forward<F>(f)( std::forward<Args>(args)...);

}

template <typename F>
class wrapper_helper;

template<typename Ret, typename... Args>
class wrapper_helper <std::function<Ret(Args...)>>
{
  std::function<Ret(Args...)> m_f;
public:
  wrapper_helper( std::function<Ret(Args...)> f ) 
      : m_f(f) {}
  Ret operator()(Args... args) const 
  { 
    return executor (m_f, args...); 
  }
};

template <typename T>
wrapper_helper<T> wrapper (T f)
{
  return wrapper_helper <T>(f);
}

int sum(int x, int y)
{
  return x + y;
}

int main (int argc, char* argv [])
{

  std::function<int(int, int)> f = sum;
  auto w = wrapper (f);

  std::cout << "Executing the wrapper" << std::endl;
  int z = w(3, 4);

  std::cout << "z = " << z << std::endl;
}
slhcrj9b

slhcrj9b4#

你可能需要

template <typename F>
class Wrapper {
public:
    Wrapper(F *func) : function(func) {}
    operator F* () { return function; }
    F *function;
};

可以像void (*funcPtr)(int) = Wrapper<void(int)>(&someFunction);这样使用

amrnrhlw

amrnrhlw5#

我想这是你想做的事情的简洁方法:

template <typename F>
F* wrapper(F* pFunc)
{
    return pFunc;
}

像这样使用它:

my_interface.func_a = wrapper(foo);
my_interface.func_a(1, 3);
hc2pp10m

hc2pp10m6#

你可以试试这个

template <class R, class... Args>
struct wrap
{
    using funct_type = R(*)(Args...);
    funct_type func;
    wrap(funct_type f): func(f) {};
    R operator()(Args&&... args)
    {
          //before code block
          std::cout << "before calling\n";
          R ret=func(std::forward<Args>(args)...);
          //after code block
          std::cout << "After calling\n";
    }
};

使用如下示例:

int somefunc(double &f, int x);
auto wrapped_somefunc=wrap{somefunc};
double f=1.0;
int x = 2;
auto result=wrapped_somefunc(f,x);
lmvvr0a8

lmvvr0a87#

这是一个用于c++17和更新的使用自动模板参数:

template <auto func, class... Args>
auto wrap_func(Args... args)
{
    std::cout << "before calling wrapped func\n";
    auto ret = func(args...);
    std::cout << "after calling wrapped func\n";
    return ret;
}

例如:

int some_func(int a, int b);
auto ret = wrap_func<some_func>(2, 3);

相关问题