*API break*, affecting you if you have added your own overloaded
visit_each() function.
An excerpt from the commit message of
https://git.gnome.org/browse/libsigc++2/commit/?id=81c778422768f14eb9ed18645a0a4352dd37c2cb
Note: This patch breaks API for some users, but it does not break ABI.
Only users who have added their own visit_each() overloads are
affected by
the API break. Their programs will still compile, but there will be
run-time
errors, if they rely on auto-disconnection of slots.
Updated instructions for users who implement their own adaptors are
found in
the description of sigc::adapts<>.
The API-breaking change will be included in the next release, which will
probably be libsigc++ 2.3.2.
Most adaptors, derived from sigc::adapts<>, have been accompanied by an
overload of sigc::visit_each(). See the description of sigc::adapts at
https://developer.gnome.org/libsigc++/2.2/structsigc_1_1adapts.html.
Bug https://bugzilla.gnome.org/show_bug.cgi?id=724496 shows that C++'s
overload resolution rules sometimes cause the wrong overload to be
selected. The way visit_each() is called has therefore been modified. A
visit_each() overload must be replaced by a specialization of struct
sigc::visitor<>. The new description of a user-defined adaptor in
sigc::adapts<> is
namespace my_ns
{
template <class T_functor>
struct my_adaptor : public sigc::adapts<T_functor>
{
template <class T_arg1=void, class T_arg2=void>
struct deduce_result_type
{ typedef typename sigc::deduce_result_type<T_functor, T_arg1,
T_arg2>::type type; };
typedef typename sigc::functor_trait<T_functor>::result_type
result_type;
//
result_type
operator()() const;
//
template <class T_arg1>
typename deduce_result_type<T_arg1>::type
operator()(T_arg1 _A_arg1) const;
//
template <class T_arg1, class T_arg2>
typename deduce_result_type<T_arg1, T_arg2>::type
operator()(T_arg1 _A_arg1, T_arg2 _A_arg2) const;
//
// Constructs a my_adaptor object that wraps the passed functor.
// Initializes adapts<T_functor>::functor_, which is invoked from
operator()().
explicit my_adaptor(const T_functor& _A_functor)
: sigc::adapts<T_functor>(_A_functor) {}
};
} // end namespace my_ns
//
// Specialization of sigc::visitor for my_adaptor.
namespace sigc
{
template <class T_functor>
struct visitor<my_ns::my_adaptor<T_functor> >
{
template <class T_action>
static void do_visit_each(const T_action& _A_action,
const my_ns::my_adaptor<T_functor>&
_A_target)
{
sigc::visit_each(_A_action, _A_target.functor_);
}
};
} // end namespace sigc
If you implement your own adaptor, you must also provide your
specialization
of sigc::visitor<>::do_visit_each<>() that will forward the call to
the functor(s)
your adapter is wrapping. Otherwise, pointers stored within the
functor won't be
invalidated when a sigc::trackable object is destroyed and you can end up
executing callbacks on destroyed objects.
Your specialization of sigc::visitor<> must be in namespace sigc.
_______________________________________________
libsigc-list mailing list
libsigc-list@gnome.org
https://mail.gnome.org/mailman/listinfo/libsigc-list