expanded parameter list for variadic template

六眼飞鱼酱① 提交于 2019-12-21 06:39:27

问题


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.


回答1:


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




回答2:


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



来源:https://stackoverflow.com/questions/3834508/expanded-parameter-list-for-variadic-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!