我正在研究基于事件的研究项目架构。系统目前使用Qt信令,但我们正试图远离Qt,所以我需要的东西几乎和Qt事件循环一样好,并且跨线程发出信号。
可能违反我的判断,我选择使用可变参数模板来创建一个通用事件,用于在目标线程中执行回调。
template<typename dest, typename... args>
class Event {
public:
Event(dest* d, void(dest::*func)(args...), args... a)
: d(d), func(func), pass(a...) { }
virtual void perform() {
(d->*func)(pass...);
}
protected:
dest* d;
void(dest::*func)(args...);
args... pass;
};
我没有找到任何表明这是否可能的东西。但是,我很难相信它不是。鉴于此,我想知道是否有办法做这样的事情,如果没有,为什么?此外,如果有人有更好的方法,我会欢迎这个建议。
答案 0 :(得分:2)
嗯。我觉得我有些讨厌。代码不是很漂亮或很好,但你可能会得到这个想法。您应该能够使用模板递归存储任何类型的对象,并在调用函数时通过它们进行递归。
#include <iostream>
template<typename first_arg, typename... args>
class Event
{
public:
Event(void (*fn)(first_arg, args...), first_arg first, args... in) : m_func(fn), var(first, in...) {}
void operator()()
{
var(m_func);
}
private:
void (*m_func)(first_arg, args...);
template <typename t_arg, typename... t_args>
struct storage;
template <typename t_arg>
struct storage<t_arg>
{
storage(t_arg t) : m_var(t) {}
template<typename t_func, typename... tt_args>
void operator()(t_func fn, tt_args... p)
{
fn(p..., m_var);
}
t_arg m_var;
};
template <typename t_arg, typename t_arg2, typename... t_args>
struct storage<t_arg, t_arg2, t_args...>
{
storage(t_arg t, t_arg2 t2, t_args... p) : m_var(t), m_storage(t2, p...) {}
template<typename t_func, typename... tt_args>
void operator()(t_func fn, tt_args... p)
{
m_storage(fn, p..., m_var);
}
t_arg m_var;
storage<t_arg2, t_args...> m_storage;
};
storage<first_arg, args...> var;
};
void test(int a, float b)
{
std::cout << a << std::endl << b << std::endl;
}
int main()
{
Event<int, float> event(test, 10, 100.0);
event();
}
另外,我认为std :: bind做了类似的事情,但不确定:D
答案 1 :(得分:0)
使用boost :: fusion :: make_fused。看例子(抱歉,日本......): http://d.hatena.ne.jp/faith_and_brave/20100804/1280905506