|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-08-08 21:23:03
On Thursday 08 August 2002 04:18 am, Brunen, Johannes wrote:
> This works pretty fine. However, when I tried to use a slot functor defined
> in class A it doesn't compile anymore:
[snip example]
> It produces the following error on MS VC++ 6.5:
>
> ..\..\..\..\Comp\Boost\boost/signals/slot.hpp(97): error C2664:
> 'boost::reference_wrapper<A::SlotFunctor const>
> boost::signals::detail::slot_base::get_invocable_slot(const A::SlotFunctor
> &,boost::signals::detail::signal_tag)': cann
> ot convert parameter 2 from 'boost::signals::detail::value_tag' to
> 'boost::signals::detail::signal_tag'
> No constructor could take the source type, or constructor overload
> resolution was ambiguous
Sorry for the delay. I'm not quite sure if it's a compiler bug or a bug in
Signals, but I'll track it down and get back to you.
> Would you be so kind to clarify the usage of slot_type, slot_function_type
> and of the automatic connection
> lifetime management a little bit for me? I would like to properly use the
> signals library.
Sure.
slot_type is the type that holds a function object that can be the target of a
signal. Any time you create a function object for the signal to call, such as
boost::bind(&A::f, this, _1), it is turned into a slot_type instance. If you
every need to pass slots around temporarily before connecting them, use
slot_type.
slot_function_type is the actual callback type that is used internally in the
signal. This is the type that does the work of translating a call to the
signal to a call to the actual callback target. If you look at the code/docs,
you'll see that the default type is a boost::function object - that's where
the flexibility regarding what you can connect as a slot comes from. You can
actually override the slot_function_type, if you want to use a different type
of callback class. At least one user has done this to make slot calls
asynchronously.
The automatic connection lifetime management lets you connect it, and forget
it. Any objects that derive from boost::signals::trackable will know about
connections they are involved in, and will disconnect those connections if
they are destroyed. For instance:
A* a = new A;
some_signal.connect(bind(&A::f, a, _1)); // #1
// ...
delete a;
some_signal(5);
This code will invoke undefined behavior normally, because there is a pointer
to 'a' in one of the slots connected to some_signal, so when we call
some_signal that slot will try to use the deleted pointer 'a'. However, if
class A derives from boost::signals::trackable, the connection made at #1
will be disconnected when A is deleted.
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk