A clean way to store a function and its (arbitrary-type, arbitrary-number) arguments

前端 未结 4 1282
广开言路
广开言路 2020-12-15 13:45

For a library, I\'d like a function to accept another function and its arguments, then store them all for calling later. The arguments must allow for any mixture of types, b

4条回答
  •  臣服心动
    2020-12-15 14:10

    An possibility is to use variadic templates and call std::bind() from within the setup() function:

    #include 
    #include 
    #include 
    #include 
    
    void myFunc1(int arg1, float arg2)
    {
        std::cout << arg1 << ", " << arg2 << '\n';
    }
    void myFunc2(const char *arg1)
    {
        std::cout << arg1 << '\n';
    }
    
    class DelayedCaller
    {
    public:
        template 
        static std::unique_ptr setup(TFunction&& a_func,
                                                    TArgs&&... a_args)
        {
            return std::unique_ptr(new DelayedCaller(
                std::bind(std::forward(a_func),
                          std::forward(a_args)...)));
        }
        void call() const { func_(); }
    
    private:
        using func_type = std::function;
        DelayedCaller(func_type&& a_ft) : func_(std::forward(a_ft)) {}
        func_type func_;
    };
    
    int main()
    {
        auto caller1(DelayedCaller::setup(&myFunc1, 123, 45.6));
        auto caller2(DelayedCaller::setup(&myFunc2, "A string"));
    
        caller1->call();
        caller2->call();
    
        return 0;
    }
    

    Output:

    123, 45.6
    A string
    

    Return a smart pointer, such as std::unique_ptr, instead of returning a raw pointer (or return by value and avoid dynamic allocation. The func_type is moveable if the arguments are moveable, or it may be quite cheap to copy anyway. You may need to define the move constructor and move assignment operator, they are generated under certain conditions).

提交回复
热议问题