How to store variadic template arguments?

前端 未结 4 2164
迷失自我
迷失自我 2020-11-27 09:56

Is it possible to store a parameter pack somehow for a later use?

template 
class Action {
private:        
    std::function

        
4条回答
  •  感情败类
    2020-11-27 10:16

    You can use std::bind(f,args...) for this. It will generate a movable and possibly copyable object that stores a copy of the function object and of each of the arguments for later use:

    #include 
    #include 
    #include 
    
    template 
    class Action {
    public:
    
      using bind_type = decltype(std::bind(std::declval>(),std::declval()...));
    
      template 
      Action(std::function f, ConstrT&&... args)
        : bind_(f,std::forward(args)...)
      { }
    
      void act()
      { bind_(); }
    
    private:
      bind_type bind_;
    };
    
    int main()
    {
      Action add([](int x, int y)
                          { std::cout << (x+y) << std::endl; },
                          3, 4);
    
      add.act();
      return 0;
    }
    

    Notice that std::bind is a function and you need to store, as data member, the result of calling it. The data type of that result is not easy to predict (the Standard does not even specify it precisely), so I use a combination of decltype and std::declval to compute that data type at compile time. See the definition of Action::bind_type above.

    Also notice how I used universal references in the templated constructor. This ensures that you can pass arguments that do not match the class template parameters T... exactly (e.g. you can use rvalue references to some of the T and you will get them forwarded as-is to the bind call.)

    Final note: If you want to store arguments as references (so that the function you pass can modify, rather than merely use, them), you need to use std::ref to wrap them in reference objects. Merely passing a T & will create a copy of the value, not a reference.

    Operational code on Coliru

提交回复
热议问题