я прочитал Вот о том, как boost: bind работает, тем более, что он — помимо прочего — генерирует что-то вроде этого:
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
Теперь я ищу что-то, что позволило бы добавить дополнительную косвенность к указателю экземпляра, чтобы он в конечном итоге выглядел так:
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return (*p_instance)->*&klass::member(0, i);
}
и может быть использован как
MyClass* pmc;
auto mfp = boost::bind(&MyClass::some_func, &pmc);
pmc = new MyClass();
mfp();
pmc = new MyClass();
mfp();
Вы могли бы использовать std::bind
а также std::ref
или их эквивалент усиления (но поскольку вы используете C ++ 11, вы можете использовать стандартные классы и функции). Итак, учитывая этот класс:
#include <iostream>
struct MyClass
{
int x;
MyClass(int x_) : x(x_) { }
void some_func()
{
std::cout << x << std::endl;
}
};
Вы можете передать указатель на функцию-член, обернутую в std::reference_wrapper
, Кроме того, избегайте использования new
(а также delete
!) и предпочитаете использовать умные указатели для моделирования владения объектом:
#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();
}
Вот живой пример.
Технически вы можете продлить boost::bind
(но нет std::bind
) с помощью get_pointer
функция:
#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();
}