我试图创建一个通用的包装器函数,它将一个函数作为模板参数,并使用与该函数相同的参数作为其参数。例如:
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。换句话说,解决方案需要是一个函数而不是一个函数对象。最重要的是,我需要能够在包装函数中完成工作。
如果内联评论不清楚,我希望能够执行以下操作:
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
在回复前两个回复时,我编辑了这个问题,以明确我需要能够在包装函数中工作(即在调用包装函数之前和之后修改一些全局状态)
答案 0 :(得分:7)
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>
。
答案 1 :(得分: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;
}
答案 2 :(得分:1)
我认为这将是你想要的简洁方式:
template <typename F>
F* wrapper(F* pFunc)
{
return pFunc;
}
并像这样使用它:
my_interface.func_a = wrapper(foo);
my_interface.func_a(1, 3);
答案 3 :(得分:0)
template <typename F>
class Wrapper {
public:
Wrapper(F *func) : function(func) {}
operator F* () { return function; }
F *function;
};
您可以使用void (*funcPtr)(int) = Wrapper<void(int)>(&someFunction);
答案 4 :(得分:0)
你可以尝试类似的东西(丑陋,但有效)
typedef