How do i write a pointer-to-member-function with std::function?

前端 未结 5 1117
刺人心
刺人心 2020-12-07 15:58

I know how to declare int fn(double) inside of std::function (std::function). I know how to write a pointer-to-member-function (

5条回答
  •  既然无缘
    2020-12-07 16:41

    std::function is perfectly capable of storing a member function pointer directly. However, you have to adjust the argument list appropriately. Member pointers must be called with an instance of the type (or a derived type). When putting them in a std::function, the first argument in the argument list is expected to be a pointer (or reference or smart-pointer) to the object type.

    So, if I have the following class:

    struct Type
    {
    public:
        int Foo();
    };
    

    The correct syntax to store this member function in a std::function is:

    std::function fooCaller = &Type::Foo;
    

    If you want to preserve the argument list (in your case, int(double)), then you need to provide the instance outside of the function. This can be done via std::bind:

    struct A{ int fn(double){ return 0; } };
    
    A anInstance;
    std::function fnCaller = std::bind(&A::fn, &anInstance, std::placeholders::_1);
    

    Note that it is your responsibility to ensure that the object pointer you provide to std::bind remains alive so long as fnCaller is alive. If you return fnCaller to someone, and it has a pointer to a stack object, you're in trouble.

    What's nice is that you could bind a shared_ptr (or any copyable smart pointer) as your object, thanks to how the function call mechanism is defined:

    struct A{ int fn(double){ return 0; } };
    
    auto anInstance = std::make_shared();
    std::function fnCaller = std::bind(&A::fn, anInstance, std::placeholders::_1);
    

    Now you don't have to worry; the binder will continue to keep the object alive, since it stores a shared_ptr by value.

提交回复
热议问题