*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

Reply via email to