Boost logo

Boost Users :

Subject: Re: [Boost-users] [Signals] trackable detection for user defined callabcks
From: Szymon Gatner (szymon.gatner_at_[hidden])
Date: 2011-10-28 15:08:41


>
> Sorry, I probably misunderstood you. I also don't quite understand
> what the documentation means by saying "User-defined function
> objects<...>do not implement the required interfaces
> for trackable object detection". Any user-defined object can inherit
> from signals::trackable and thus "implement the required interfaces".
> boost::function (and of course, std::function etc) really doesn't
> provide such a functionality as far as I know, and I'm not sure it's
> possible to add it externally.

Yup, it is about something different. Mind that signal does not store
pointers to signalled objects directly. It stores slots which are bound
to such object. The way Signals are implemented this works correctly:

class Trackable : public signals::trackable
{
  void foo() {}
}

signal<void()> sig;
Trackable t;
sig.connect(bind(&Trackable::foo, &b));

// this does not work tho:
// boost::function<void()> func = bind(&Trackable::foo, &t);
// sig.connect(func)

sig();

even tho sig stores function object returned from bind which is obviously
not derived from trackable but only keeps a (smart)pointer to trackable
object. Docs clearly state this:

"At this time there is a significant limitation to the use of trackable objects
in making slot connections: function objects built using Boost.Bind are
understood, such that pointers or references to trackable objects passed to
boost::bind will be found and tracked."

So it is in fact NOT enough to derive from trackable class but also a callback
type must be "understood" / "implement the required interfaces".

>
> If your objects have to be managed by other types of smart-ptrs, you
> still can use weak_ptr for tracking:
> struct your_class
> {
>  your_class() : track_(new int())
>  {}
> private:
>  shared_ptr<void> track_;
> }
>

Yeah, that is what I just love about libraries designed in this way, to be able
to use it, dummy shared_ptr member must be added to class definition even
tho it does not actually share anything. Enforcing memory model is bad but what
is worst in this design imho is that instead of just making new class trackable
(implementation detail) with Signals2 tracking must be explicit at sig.connect()
site, so what works with Signals1 is broken with Signals2:

void Foo::func()
{
  connectMe(bind(&Foo:func, this));
}

void template <class Slot>
void connectMe(Slot slot)
{
  sig.connect(slot); // if sig is Signal1 signal automatic tracking
will work if class Foo
                            // is derived from trackable (as binders
from bind() and recognized)
                            // but there is no way of making original
object trackable with Signals2
                            // as there is no shared_ptr to pass anymore
}

>
> Well... at least, you can typedef mutex_type<bs2::dummy_mutex> :).

And get 1 more line to write, no thanks ;)

Cheers


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net