#include <iostream>
#include <unordered_set>
template < typename T > struct magic
{
magic() { objects.insert( static_cast<T*>(this) ) ; }
magic( const magic& ) : magic() {}
magic( magic&& ) : magic() {}
~magic() { objects.erase( static_cast<T*>(this) ) ; }
template< typename FN > static void for_each_instance( FN fn )
{ for( T* p : objects ) fn(p) ; }
static std::unordered_set<T*> objects ;
};
template < typename T > std::unordered_set<T*> magic<T>::objects ;
struct A : magic<A>
{
void foo( int i, char c )
{ std::cout << "A::foo( " << this << ", " << i << ", " << c << " )\n" ; }
};
struct B : magic<B>
{
void bar( double d ) const
{ std::cout << "B::bar( " << this << ", " << d << " )\n" ; }
};
int main()
{
A one ;
B two ;
{
A three = one ;
B b[2] ;
A::for_each_instance( []( A* p ) { p->foo( 99, 'X' ) ; } ) ;
B::for_each_instance( []( B* p ) { p->bar( 12.8 ) ; } ) ;
}
std::cout << "------------------------\n" ;
A::for_each_instance( []( A* p ) { p->foo( -7, 'Y' ) ; } ) ;
B::for_each_instance( []( B* p ) { p->bar( 123.45 ) ; } ) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dW5vcmRlcmVkX3NldD4KCnRlbXBsYXRlIDwgdHlwZW5hbWUgVCA+IHN0cnVjdCBtYWdpYwp7CiAgICBtYWdpYygpIHsgb2JqZWN0cy5pbnNlcnQoIHN0YXRpY19jYXN0PFQqPih0aGlzKSApIDsgfQogICAgbWFnaWMoIGNvbnN0IG1hZ2ljJiApIDogbWFnaWMoKSB7fQogICAgbWFnaWMoIG1hZ2ljJiYgKSA6IG1hZ2ljKCkge30KICAgIH5tYWdpYygpIHsgb2JqZWN0cy5lcmFzZSggc3RhdGljX2Nhc3Q8VCo+KHRoaXMpICkgOyB9CgogICAgdGVtcGxhdGU8IHR5cGVuYW1lIEZOID4gc3RhdGljIHZvaWQgZm9yX2VhY2hfaW5zdGFuY2UoIEZOIGZuICkKICAgIHsgZm9yKCBUKiBwIDogb2JqZWN0cyApIGZuKHApIDsgfQoKICAgIHN0YXRpYyBzdGQ6OnVub3JkZXJlZF9zZXQ8VCo+IG9iamVjdHMgOwp9OwoKdGVtcGxhdGUgPCB0eXBlbmFtZSBUID4gc3RkOjp1bm9yZGVyZWRfc2V0PFQqPiBtYWdpYzxUPjo6b2JqZWN0cyA7CgpzdHJ1Y3QgQSA6IG1hZ2ljPEE+CnsKICAgIHZvaWQgZm9vKCBpbnQgaSwgY2hhciBjICkKICAgIHsgc3RkOjpjb3V0IDw8ICJBOjpmb28oICIgPDwgdGhpcyA8PCAiLCAiIDw8IGkgPDwgIiwgIiA8PCBjIDw8ICIgKVxuIiA7IH0KfTsKCnN0cnVjdCBCIDogbWFnaWM8Qj4KewogICAgdm9pZCBiYXIoIGRvdWJsZSBkICkgY29uc3QKICAgIHsgc3RkOjpjb3V0IDw8ICJCOjpiYXIoICIgPDwgdGhpcyA8PCAiLCAiIDw8IGQgPDwgIiApXG4iIDsgfQp9OwoKaW50IG1haW4oKQp7CiAgICBBIG9uZSA7CiAgICBCIHR3byA7CiAgICB7CiAgICAgICAgQSB0aHJlZSA9IG9uZSA7CiAgICAgICAgQiBiWzJdIDsKICAgICAgICBBOjpmb3JfZWFjaF9pbnN0YW5jZSggW10oIEEqIHAgKSB7IHAtPmZvbyggOTksICdYJyApIDsgfSApIDsKICAgICAgICBCOjpmb3JfZWFjaF9pbnN0YW5jZSggW10oIEIqIHAgKSB7IHAtPmJhciggMTIuOCApIDsgfSApIDsKICAgIH0KICAgIHN0ZDo6Y291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iIDsKICAgIEE6OmZvcl9lYWNoX2luc3RhbmNlKCBbXSggQSogcCApIHsgcC0+Zm9vKCAtNywgJ1knICkgOyB9ICkgOwogICAgQjo6Zm9yX2VhY2hfaW5zdGFuY2UoIFtdKCBCKiBwICkgeyBwLT5iYXIoIDEyMy40NSApIDsgfSApIDsKfQo=
A::foo( 0xbfaa5073, 99, X )
A::foo( 0xbfaa5071, 99, X )
B::bar( 0xbfaa5077, 12.8 )
B::bar( 0xbfaa5076, 12.8 )
B::bar( 0xbfaa5072, 12.8 )
------------------------
A::foo( 0xbfaa5071, -7, Y )
B::bar( 0xbfaa5072, 123.45 )