通用回调 [英] Generic callbacks
问题描述
因此,我正在尝试更好地学习模板元编程,并且我认为这是一个很好的练习.
So, I'm trying to learn template metaprogramming better and I figure this is a good exercise for it.
我正在尝试编写可回调函数的代码,这些函数可以带有我喜欢传递给它的任意数量的参数.
I'm trying to write code that can callback a function with any number of arguments I like passed to it.
// First function to call
int add( int x, int y ) ;
// Second function to call
double square( double x ) ;
// Third func to call
void go() ;
回调创建代码应类似于:
The callback creation code should look like:
// Write a callback object that
// will be executed after 42ms for "add"
Callback<int, int, int> c1 ;
c1.func = add ;
c1.args.push_back( 2 ); // these are the 2 args
c1.args.push_back( 5 ); // to pass to the "add" function
// when it is called
Callback<double, double> c2 ;
c2.func = square ;
c2.args.push_back( 52.2 ) ;
我的想法是,使用 template元编程我希望能够像这样声明回调,编写这样的结构(请记住,这是非常PSEUDOcode)
What I'm thinking is, using template metaprogramming I want to be able to declare callbacks like, write a struct like this (please keep in mind this is VERY PSEUDOcode)
<TEMPLATING ACTION <<ANY NUMBER OF TYPES GO HERE>> >
struct Callback
{
double execTime ; // when to execute
TYPE1 (*func)( TYPE2 a, TYPE3 b ) ;
void* argList ; // a stored list of arguments
// to plug in when it is time to call __func__
} ;
因此,当用
Callback<int, int, int> c1 ;
您会自动通过<硬式模板动作>像
You would automatically get constructed for you by < HARDCORE TEMPLATING ACTION > a struct like
struct Callback
{
double execTime ; // when to execute
int (*func)( int a, int b ) ;
void* argList ; // this would still be void*,
// but I somehow need to remember
// the types of the args..
} ;
是否有正确的方向开始编写此指南?
Any pointers in the right direction to get started on writing this?
推荐答案
You can do this with variadic templates, which your compiler may not support. I've never used them myself and thus may get some of the details wrong, but I'll try to describe them.
可变参数模板使用"..."运算符.在模板声明(或其他类型表达式)中,省略号表示形式参数可以带有任意数量的参数.
Variadic templates use the "..." operator. Within a template declaration (or other type expressions), ellipses indicate that the formal parameter may take any number of arguments.
template <typename ... Args>
class Variadic {
public:
operator()(Args&& ... args);
};
在函数调用表达式中,省略号将其左参数解包.
Within a function call expression, ellipses unpack their left argument.
Variadic<Args>::operator(Args&& ... args) {
func(args...);
}
要转发,您可能需要使用std::forward
;这是我的知识变得模糊的领域.放在一起,我们得到:
To forward, you might need to use std::forward
; this is one area where my knowledge grows fuzzy. Put this together, and we get:
template <typename ReturnValue, typename ... Args>
class Callback {
typedef ReturnValue (*Func)(Args ... args);
double execTime;
Func func;
Args... args;
public:
Callback(double et, Func f) : execTime(et), func(f) {}
ReturnValue operator()(Args&& ... a);
ReturnValue operator()();
};
template <typename ReturnValue, typename ... Args>
ReturnValue Callback<ReturnValue, Args>::operator()(Args&& ... a) {
return (*func)(std::forward(a)...);
}
template <typename ReturnValue, typename ... Args>
ReturnValue Callback<ReturnValue, Args>::operator()() {
return operator(*func)(args...);
}
这篇关于通用回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!