How to store variadic template arguments?

前端 未结 4 2165
迷失自我
迷失自我 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:15

    To accomplish what you want done here, you'll have to store your template arguments in a tuple:

    std::tuple args;
    

    Furthermore, you'll have to change up your constructor a bit. In particular, initializing args with an std::make_tuple and also allowing universal references in your parameter list:

    template 
    Action(F&& func, Args&&... args)
        : f(std::forward(func)),
          args(std::forward(args)...)
    {}
    

    Moreover, you would have to set up a sequence generator much like this:

    namespace helper
    {
        template 
        struct index {};
    
        template 
        struct gen_seq : gen_seq {};
    
        template 
        struct gen_seq<0, Is...> : index {};
    }
    

    And you can implement your method in terms of one taking such a generator:

    template 
    void func(std::tuple& tup, helper::index)
    {
        f(std::get(tup)...);
    }
    
    template 
    void func(std::tuple& tup)
    {
        func(tup, helper::gen_seq{});
    }
    
    void act()
    {
       func(args);
    }
    

    And that it! So now your class should look like this:

    template 
    class Action
    {
    private:
        std::function f;
        std::tuple args;
    public:
        template 
        Action(F&& func, Args&&... args)
            : f(std::forward(func)),
              args(std::forward(args)...)
        {}
    
        template 
        void func(std::tuple& tup, helper::index)
        {
            f(std::get(tup)...);
        }
    
        template 
        void func(std::tuple& tup)
        {
            func(tup, helper::gen_seq{});
        }
    
        void act()
        {
            func(args);
        }
    };
    

    Here is your full program on Coliru.


    Update: Here is a helper method by which specification of the template arguments aren't necessary:

    template 
    Action make_action(F&& f, Args&&... args)
    {
        return Action(std::forward(f), std::forward(args)...);
    }
    
    int main()
    {
        auto add = make_action([] (int a, int b) { std::cout << a + b; }, 2, 3);
    
        add.act();
    }
    

    And again, here is another demo.

提交回复
热议问题