指向方法的指针/传递这个指针/ boost::bind

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

本文关键字:指针 boost bind 方法      更新时间:2023-10-16

我想知道"这个"指针是如何从类传递给方法的。让我们看看这段代码:

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;
}

假设绑定像函数对象一样工作,它以某种方式传递这个/object指针。如果我想显式地这样做,我会得到一个编译错误。

它实际上是如何工作的?

boost::bind识别出它包装的目标是指向成员的指针,并使用不同的代码路径使用指向成员的指针的正确语法来调用它。

像编程中的大多数问题一样,您可以通过添加一个间接级别来解决它。bind可以对它的目标应用一个转换,这样一个指向成员的指针将被改编成一个可以像普通的函数对象一样调用的东西,并照顾细节,所以bind本身不需要知道细节。

函数boost::mem_fn可用于将指向成员的指针转换为可调用对象:

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

所以给定这个适配器,bind只需要确保它在需要的时候被使用。

在GCC实现中,我们有这样的东西:

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); }

其中mem_fn_wrapperstd::mem_fn函数返回的类型。所以bind可以使用wrap_mem_ptr来确保它所包装的对象可以被统一调用