#include <iostream>
#include <unordered_set>
#include <memory>

template < typename T, typename TAG = void  > struct magic
{
    // ...
    /* private: */ static std::unordered_set<T*> objects ;
};

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

template < typename T, typename TAG = void > struct tracked
                                              : T, magic< tracked<T,TAG>, TAG >
{
    template < typename ... ARGS > tracked( ARGS... args ) : T(args...) {}
};

struct A { /* ... */ };

template < int N > struct use_case {} ;

int main()
{
    std::cout << std::addressof( tracked<A>::objects ) << '\n' ;
    std::cout << std::addressof( tracked< A, use_case<1> >::objects ) << '\n' ;
    std::cout << std::addressof( tracked< A, use_case<2> >::objects ) << '\n' ;
    std::cout << std::addressof( tracked< A, use_case<3> >::objects ) << '\n' ;
    std::cout << std::addressof( tracked< A, use_case<4> >::objects ) << '\n' ;
    std::cout << std::addressof( tracked< A, use_case<5> >::objects ) << '\n' ;
}
