-1

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

Nicolas Henneaux
  • 11,507
  • 11
  • 57
  • 82
danilabagroff
  • 602
  • 1
  • 7
  • 23

1 Answers1

2

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().

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Cheers! Using this and static_pointer_cast feels like I'm coming in on a wing... OCD? ;) Would be a redesign (to avoid this stuff) the best solution? – danilabagroff Mar 13 '15 at 08:52