#include <iostream>
#include <sigc++/sigc++.h>


class Standalone
   : public sigc::trackable
{
public:
   Standalone()
   {
      cnx = signal.connect(sigc::bind(sigc::mem_fun(this, &Standalone::foo),
                                      sigc::ref(*this)));
   }

   ~Standalone()
   {
      //cnx.disconnect(); // This avoids the crash.
      sigc::trackable::notify_callbacks();
   }

   void foo(const Standalone& foo) { }

   sigc::signal<void> signal;
   sigc::connection cnx;
};


class LongLived
   : public sigc::trackable
{
public:
   LongLived() { }

   sigc::signal<void> signal;
};


class ShortLived
   : public sigc::trackable
{
public:
   ShortLived(LongLived& longLived)
   {
      cnx = longLived.signal.connect(sigc::bind(sigc::mem_fun(this, &ShortLived::foo),
                                                sigc::ref(*this)));
   }

   ~ShortLived()
   {
      //cnx.disconnect(); // This avoids the crash.
   }

   void foo(const ShortLived& shortLived) { }

   sigc::connection cnx;
};


void foo(const sigc::trackable& t1, const sigc::trackable& t2) { }


int main(void)
{
   {
      sigc::signal<void> signal;
      sigc::trackable* trackable = new sigc::trackable;
      signal.connect(sigc::bind(sigc::ptr_fun(&foo),
                                sigc::ref(*trackable),
                                sigc::ref(*trackable)));
      delete trackable;
   }
   std::cout << "Case 1 succeeded." << std::endl;

   {
      Standalone foo;
   }
   std::cout << "Case 2 succeeded." << std::endl;

   {
      LongLived longLived;
      ShortLived shortLived(longLived);
   }
   std::cout << "Case 3 succeeded." << std::endl;
   return 0;
}
