I'm trying to make a forwarding call wrapper with std::bind() of an internal member function inside instance which has been created as a shared_ptr<>. Look like there's no chance.
In a nutshell:
std::shared_ptr<Parent> _instance(std::make_shared<Child>());
_instance->init();
_instance->proc();
class Parent : std::enable_shared_from_this<Parent>
{
protected:
std::vector<std::function<void()>> _vector;
public:
virtual void init() = 0;
virtual void proc() final
{
for (auto& f : _vector) {
f();
}
}
};
class Child : public Parent
{
protected:
std::string _s1;
int _i1;
public:
virtual void init() override
{
// XXX Won't compile
_vector.push_back(std::bind(&Child::bingo, shared_from_this()));
// BUG Looks bad in case when current "this" has been wrapped by shared_ptr<Parent>
_vector.push_back(std::bind(&Child::bingo, this));
// NOTE Lambda doesn't work here as well, because I need an access(in the ::bingo()) to the data members
}
void bingo()
{
std::cout << "Bingo!" << _s1 << _i1 << std::endl;
}
};
This is not a real-life example, in case if someone would like to offer a redesign as a solution ;)
Binding to a raw pointer (this
) isn't particularly bad here. The function is stored in a vector within this object, so the pointer will remain valid as long as it's accessible from that vector. You'll only have a problem if you copy the function out of the vector, then try to call it after destroying the object.
If you do want a shared pointer, you'll need to convert from a pointer to Parent
(which shared_from_this()
gives you) to a pointer to Child
(whose member you want to call):
static_pointer_cast<Child>(shared_from_this());
A lambda will work just as well as a bind
thingy, as long as it captures this
or shared_from_this()
.