Passing member function with all arguments to std::function

前端 未结 3 992
醉梦人生
醉梦人生 2020-12-24 15:52

How can I create a std::function from member function without need for typing std::placeholders::_1, std::placeholders::_2, etc - I would like to \"placehold\" all arguments

3条回答
  •  别那么骄傲
    2020-12-24 16:18

    You can use function template which will deduce all member function parameter types, like this:

    template
    auto make_delegate(const Obj &x, Result (Obj::*fun)(Args...)) -> // ...
    

    And will return special delegate object, which will contain your object (or pointer to it) and just forward all passed arguments to member function of underlying object:

    template
    struct Delegate
    {
        Obj x;
        Result (Obj::*f)(Args...);
    
        template
        Result operator()(Ts&&... args)
        {
            return (x.*f)(forward(args)...);
        }
    };
    

    You will get following usage syntax:

    function fun = make_delegate(object, &Foo::bar);
    

    Here is full example:

    #include 
    #include 
    #include 
    
    using namespace std;
    
    struct Foo
    {
        int bar(int x, float y, bool z)
        {
            cout << "bar: " << x << " " << y << " " << z << endl;
            return 0;
        }
    };
    
    int baz(int x, float y, bool z)
    {
        cout << "baz: " << x << " " << y << " " << z << endl;
        return 0;
    }
    
    template
    struct Delegate
    {
        Obj x;
        Result (Obj::*f)(Args...);
    
        template
        Result operator()(Ts&&... args)
        {
            return (x.*f)(forward(args)...);
        }
    };
    
    template
    auto make_delegate(const Obj &x, Result (Obj::*fun)(Args...))
        -> Delegate
    {
        Delegate result{x, fun};
        return result;
    }
    
    int main()
    {
        Foo object;
        function fun[] =
        {
            baz,
            make_delegate(object, &Foo::bar) // <---- usage
        };
        for(auto &x : fun)
            x(1, 1.0, 1);
    }
    

    Output is:

    baz: 1 1 1
    bar: 1 1 1
    

    Live Demo on Coliru

提交回复
热议问题