Search code examples
c++boostc++11binddispatch

Is it possible to boost::bind to a member function of a known class but a (yet) unknown object?


I have read here about how boost:bind works, especially that it - besides other things - generates something like this:

struct unspecified_type
{
  ... some members ...
  return_type operator()(int i) const { return instance->*&klass::member(0, i);
}

Now, I'm looking for something which would allow to add an additional indirection to the instance pointer, so that it ultimatively would look like this:

struct unspecified_type
{
  ... some members ...
  return_type operator()(int i) const { return (*p_instance)->*&klass::member(0, i);
}

and could be used like

MyClass* pmc;
auto mfp = boost::bind(&MyClass::some_func, &pmc);
pmc = new MyClass();
mfp();
pmc = new MyClass();
mfp();

Solution

  • You could use std::bind and std::ref, or their boost equivalent (but since you are using C++11, you may want to use standard classes and functions). So given this class:

    #include <iostream>
    
    struct MyClass
    {
        int x;
        MyClass(int x_) : x(x_) { }
        void some_func()
        {
            std::cout << x << std::endl;
        }
    };
    

    You could pass the pointer on which the member function is to be invoked wrapped in an std::reference_wrapper. Also, avoid using new (and delete!) and prefer using smart pointers for modeling object ownership:

    #include <functional>
    #include <memory>
    
    int main(int argc, char *argv[])
    {
        std::shared_ptr<MyClass> pmc;
        auto mfp = std::bind(&MyClass::some_func, std::ref(pmc));
    
        pmc = std::make_shared<MyClass>(42);
        mfp();
    
        pmc = std::make_shared<MyClass>(1729);
        mfp();
    }
    

    Here is a live example.