Domanda

Sto lavorando su un'architettura basata sugli eventi per un progetto di ricerca. Il sistema usa la modalità di segnalazione Qt, ma stiamo cercando di allontanarsi dalla Qt, quindi ho bisogno di qualcosa che funziona quasi come il ciclo degli eventi Qt e segnali attraverso i thread.

Probabilmente contro il mio giudizio migliore, ho scelto di utilizzare i modelli variadic per creare un evento generico che verrà utilizzato per effettuare la richiamata nel thread di destinazione.

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

Non ho trovato nulla che indica se questo è possibile. Tuttavia, ho difficoltà a credere che non lo è. Dato che, mi chiedevo se c'è un modo per fare qualcosa di simile, e se non c'è, perché? Inoltre, se qualcuno ha un modo migliore di fare questo vorrei accogliere il suggerimento.

È stato utile?

Soluzione

Hm. Credo di aver trovato qualcosa di brutto. Il codice non è molto bello o buono, ma probabilmente l'idea. Si dovrebbe essere in grado di utilizzare i modelli per memorizzare in modo ricorsivo oggetti di qualsiasi tipo, e anche recurse attraverso di loro quando si chiama la funzione.

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

Inoltre, penso che std :: bind fa qualcosa di simile, ma non è sicuro: D

Altri suggerimenti

uso boost :: :: fusione make_fused. vedi esempio (mi dispiace, giapponese ...): http://d.hatena.ne.jp/faith_and_brave/20100804/1280905506

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top