расширенный список параметров для вариационного шаблона

Я работаю над архитектурой на основе событий для исследовательского проекта. В настоящее время система использует сигнализацию 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;
};

Я не нашел ничего, что указывало бы, возможно ли это. Однако мне трудно поверить, что это не так. Учитывая это, мне было интересно, есть ли способ сделать что-то подобное и если нет, то почему? Кроме того, если у кого-то есть лучший способ сделать это, я бы приветствовал это предложение.

 MSN30 сент. 2010 г., 22:35
Чтобы ответить на ваш первый вопрос, вы пытались это скомпилировать?
 Luc Touraille01 окт. 2010 г., 08:51
Если вы хотите что-то действительно похожее на сигналы Qt, но без использования Qt, вы можете попробоватьBoost.Signals (или посмотрите на код, чтобы черпать вдохновение, но они еще не используют C ++ 0x).
 Alex Norton03 окт. 2010 г., 10:08
Да, я пытался это скомпилировать, и единственная часть, которая доставляет неприятности, это аргументы ... проход внизу.
 lurscher27 нояб. 2010 г., 05:54
-1 за то, что я не объявил явного победителя почти через месяц (ответ Маистера - самый наглядный пример, который я до сих пор нашел для шаблонов с переменным числом аргументов)

Ответы на вопрос(2)

используйте boost :: fusion :: make_fused. посмотрите пример (извините, японский ...):http://d.hatena.ne.jp/faith_and_brave/20100804/1280905506

Решение Вопроса

Гектометр Я думаю, что я получил что-то противное. Код не очень красивый или хороший, но вы, вероятно, поняли идею. Вы должны иметь возможность использовать шаблоны для рекурсивного хранения объектов любого типа, а также проходить через них при вызове функции.

#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

Ваш ответ на вопрос