2010-09-30 18 views
0

Je travaille sur une architecture basée sur les événements pour un projet de recherche. Le système utilise actuellement la signalisation Qt, mais nous essayons de nous éloigner de Qt, j'ai donc besoin de quelque chose qui fonctionnera presque aussi bien que la boucle d'événements Qt et les signaux à travers les threads. Probablement contre mon meilleur jugement, j'ai choisi d'utiliser des modèles variadic pour créer un événement générique qui sera utilisé pour effectuer le rappel dans le thread de destination.Liste de paramètres étendue pour le modèle variadique

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

Je n'ai rien trouvé qui indique si cela est possible. Cependant, j'ai du mal à croire que ce n'est pas le cas. Compte tenu de cela, je me demandais s'il y avait un moyen de faire quelque chose comme ça et s'il n'y en a pas, pourquoi? Aussi, si quelqu'un a une meilleure façon de faire cela, je serais heureux de la suggestion.

+0

Pour répondre à votre première question, avez-vous essayé de compiler ceci? – MSN

+0

Si vous voulez quelque chose de vraiment similaire aux signaux Qt, mais sans utiliser Qt, vous pouvez essayer [Boost.Signals] (http://www.boost.org/doc/libs/1_43_0/doc/html/signals.html) (ou regardez le code pour dessiner un peu d'inspiration, mais ils n'utilisent pas encore C++ 0x). –

+0

Oui, j'ai essayé de compiler ceci, et la seule partie qui pose problème est celle des args ... passer en bas. –

Répondre

2

Hm. Je pense que j'ai quelque chose de méchant. Le code n'est pas très beau ou bon, mais vous avez probablement l'idée. Vous devriez être capable d'utiliser des modèles pour stocker de façon récursive des objets de n'importe quel type, et aussi de les parcourir lors de l'appel de la fonction.

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

En outre, je pense que std :: bind quelque chose de similaire, mais pas sûr: D