简体   繁体   中英

Pointer to the method / passing this pointer / boost::bind

I'm wondering how "this" pointer is being passed to the methods from the class. Let's see this snippet of code:

class CTest
{
public:
    CTest(int n_) : n(n_) {}
    void method()
    {
        std::cout << n << std::endl;
    }
private:
    int n;
};

int main()
{
    CTest t1(100);

    boost::bind(&CTest::method, &t1)(); //100
    boost::bind(&CTest::method, _1)(&t1); //100
    Test::method(&t1); //no matching function for call to ‘CTest::method(CTest*)’

    return 0;
}

Assuming the bind works just like a function object, it passes this/object pointer somehow. If I want to do it explicitly I get an compilation error.

How does it work in fact?

boost::bind recognises when the target it wraps is a pointer to member, and uses a different code path that calls it using the right syntax for a pointer to member.

Like most problems in programming, you can solve it by adding a level of indirection. bind can apply a transformation to its target so that a pointer to member will be adapted into something that can be called like a normal function object, and takes care of the details, so bind itself doesn't need to know the details.

The function boost::mem_fn can be used to transform a pointer to member into a callable object:

void (CTest::*memptr)() = &CTest::method;
CTest* p = &t1;
auto callable = boost::mem_fn(memptr);
callable(p);  // calls (p.->*memptr)()

So given that adaptor, bind only needs to ensure it is used whenever needed.

In the GCC implementation we have something like this:

template<class T>
struct maybe_wrap_mem_ptr
{
  typedef T type;
};

// partial specialization for pointer to member
template<class R, class C>
struct maybe_wrap_mem_ptr<R C::*>
{
  typedef mem_fn_wrapper<R C::*> type;
};

template<class T>
typename maybe_wrap_mem_ptr<T>::type
wrap_mem_ptr(T t)
{ return typename maybe_wrap_mem_ptr<T>::type(t); }

Where mem_fn_wrapper is the type returned by the std::mem_fn function. So bind can just use wrap_mem_ptr to ensure that the object it wraps can be called uniformly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM