0

I'm working on an Event based architecture for a research project. The system currently uses Qt signalling, but we are trying to move away from Qt, so I need something that will work almost as well as the Qt event loop and signals across threads.

Probably against my better judgement, I've chosen to use variadic templates to create a generic event that will be used to perform the callback in the destination thread.

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

I haven't found anything that indicates if this is possible. However, I have a hard time believing that it isn't. Given that, I was wondering if there is a way to do something like this and if there isn't, why? Also, if anybody has a better way of doing this I would welcome the suggestion.

4
  • To answer your first question, did you try to compile this? Commented Sep 30, 2010 at 20:35
  • If you want something really similar to Qt signals, but without using Qt, you could try Boost.Signals (or look at the code to draw some inspiration, but they don't use C++0x yet). Commented Oct 1, 2010 at 6:51
  • Yes I did try to compile this, and the only part that gives trouble is the args... pass at the bottom. Commented Oct 3, 2010 at 8:08
  • -1 for not declaring a clear winner after almost a month (Maister answer is the most clear example i've found of variadic templates so far) Commented Nov 27, 2010 at 4:54

2 Answers 2

2

Hm. I think I got something nasty. The code is not very pretty or good, but you probably get the idea. You should be able to use templates to recursively store objects of any type, and also recurse through them when calling the function.

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

Also, I think std::bind does something similar, but not sure :D

Sign up to request clarification or add additional context in comments.

Comments

0

use boost::fusion::make_fused. see example(sorry, japanese...): http://d.hatena.ne.jp/faith_and_brave/20100804/1280905506

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.