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.