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

StackOverflow https://stackoverflow.com/questions/16608723

سؤال

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();
هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

Technically, you can extend boost::bind (but not std::bind) using get_pointer function:

#include <boost/bind.hpp>
struct MyClass
{
  void some_func()
  {}
};

namespace boost
{
  template<class T>
  T *get_pointer(T **t)
  {
    return *t;
  }
}

int main()
{
  MyClass *pmc;
  auto mfp = boost::bind(&MyClass::some_func, &pmc);
  pmc = new MyClass();
  mfp();
  pmc = new MyClass();
  mfp();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top