#include <iostream>
#include <unordered_set>

template < typename T > struct magic
{
    magic() : enable_for_each_instance(false) {}

    magic( bool b) : enable_for_each_instance(b)
    { if(b) objects.insert( static_cast<T*>(this) ) ; }

    magic( const magic& that ) : magic(that.enable_for_each_instance) {}

    magic( magic&& that ) : magic(that.enable_for_each_instance) {}

    ~magic() { if(enable_for_each_instance) objects.erase( static_cast<T*>(this) ) ; }

    template< typename FN > static void for_each_instance( FN fn )
    { for( T* p : objects ) fn(p) ; }

    const bool enable_for_each_instance ;
    private: static std::unordered_set<T*> objects ;
};

template < typename T > std::unordered_set<T*> magic<T>::objects ;

struct A : magic<A>
{
    explicit A( bool enable_magic = false ) : magic<A>(enable_magic) {}
    void foo( int i, char c )
    { std::cout << "A::foo( " << this << ", " << i << ", " << c << " )\n" ; }
};

struct B : magic<B>
{
    explicit B( bool enable_magic = false ) : magic<B>(enable_magic) {}
    void bar( double d ) const
    { std::cout << "B::bar( " << this << ", " << d << " )\n" ; }
};

int main()
{
    A one(true), x ;
    B two(true), y ;
    {
        A three = one ;
        B four, five = two ;
        A a[1000] ;
        B b[25] ;
        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 ) ; } ) ;
}
