@@ -371,8 +371,14 @@ struct signal_emit<void, void, T_arg...>
371371
372372} /* namespace internal */
373373
374+ // TODO: When we can break ABI, let signal_base instead of signal_with_accumulator
375+ // derive from trackable, as in sigc++2. One of them must derive from trackable.
376+ // Otherwise the slot returned from signal_with_accumulator::make_slot() is not
377+ // automatically disconnected when the signal is deleted.
378+ // https://github.com/libsigcplusplus/libsigcplusplus/issues/80
379+
374380/* * Signal declaration.
375- * signal_with_accumulator can be used to connect() slots that are invoked
381+ * % signal_with_accumulator can be used to connect() slots that are invoked
376382 * during subsequent calls to emit(). Any functor or slot
377383 * can be passed into connect(). It is converted into a slot
378384 * implicitly.
@@ -396,7 +402,9 @@ struct signal_emit<void, void, T_arg...>
396402 * @ingroup signal
397403 */
398404template <typename T_return, typename T_accumulator, typename ... T_arg>
399- class signal_with_accumulator : public signal_base
405+ class signal_with_accumulator
406+ : public signal_base
407+ , public trackable
400408{
401409public:
402410 using slot_type = slot<T_return(T_arg...)>;
@@ -461,11 +469,6 @@ class signal_with_accumulator : public signal_base
461469 }
462470
463471 /* * Creates a functor that calls emit() on this signal.
464- *
465- * @note %sigc::signal does not derive from sigc::trackable in sigc++3.
466- * If you connect the returned functor (calling %emit() on signal1) to
467- * another signal (signal2) and then delete signal1, you must manually
468- * disconnect signal1 from signal2 before you delete signal1.
469472 *
470473 * @code
471474 * sigc::mem_fun(mysignal, &sigc::signal_with_accumulator::emit)
@@ -485,19 +488,28 @@ class signal_with_accumulator : public signal_base
485488
486489 signal_with_accumulator () = default ;
487490
488- signal_with_accumulator (const signal_with_accumulator& src) : signal_base(src) {}
491+ signal_with_accumulator (const signal_with_accumulator& src) : signal_base(src), trackable(src) {}
489492
490- signal_with_accumulator (signal_with_accumulator&& src) : signal_base(std::move(src)) {}
493+ signal_with_accumulator (signal_with_accumulator&& src)
494+ : signal_base(std::move(src)), trackable(std::move(src))
495+ {
496+ }
491497
492498 signal_with_accumulator& operator =(const signal_with_accumulator& src)
493499 {
494500 signal_base::operator =(src);
501+ // Don't call trackable::operator=(src).
502+ // It calls notify_callbacks(). This signal is not destroyed.
495503 return *this ;
496504 }
497505
498506 signal_with_accumulator& operator =(signal_with_accumulator&& src)
499507 {
500508 signal_base::operator =(std::move (src));
509+ if (src.impl_ != impl_)
510+ src.notify_callbacks ();
511+ // Don't call trackable::operator=(std::move(src)).
512+ // It calls notify_callbacks(). This signal is not destroyed.
501513 return *this ;
502514 }
503515};
@@ -531,7 +543,7 @@ class signal_with_accumulator : public signal_base
531543 * @par Example:
532544 * @code
533545 * void foo(int) {}
534- * sigc::signal<void, long> sig;
546+ * sigc::signal<void( long) > sig;
535547 * sig.connect(sigc::ptr_fun(&foo));
536548 * sig.emit(19);
537549 * @endcode
0 commit comments