C++ instance counter I have created template class to easily get the current number of instances a class has. It's threadsafe and I tried to make it as hard as possible to abuse.

#include &lt;atomic&gt;
#include &lt;cstdint&gt;
#include &lt;type_traits&gt;


template&lt;typename t_derived&gt;
struct countable
{
    friend t_derived;

    struct counter
    {
        friend countable&lt;t_derived&gt;;

    private:
        static std::atomic&lt;uint32_t&gt; s_counter;
    };

    static uint32_t instances()
    {
        static_assert(std::is_base_of&lt;countable&lt;t_derived&gt;, t_derived&gt;::value,
                      "Trying to get count of non counted class");
        return counter::s_counter;
    }

private:
    countable()
    {
        ++counter::s_counter;
    }

    countable(const countable&amp;)
    {
        ++counter::s_counter;
    }

    ~countable()
    {
        --counter::s_counter;
    }
};

template&lt;typename t_derived&gt;
std::atomic&lt;uint32_t&gt; countable&lt;t_derived&gt;::counter::s_counter(0);


Edit:

There seem to be some misunderstandings about this class. I'm sorry, I should've explained it a bit. Here is an example main.cpp. It requires at least C++11:

#include &lt;iostream&gt;

// paste implementation here


struct counted1 : countable&lt;counted1&gt;
{
    counted1()
    {
        std::cout &lt;&lt; "counted1::counted1()\n";
    }
    ~counted1()
    {
        std::cout &lt;&lt; "counted1::~counted1()\n";
    }
};

struct counted2 : countable&lt;counted2&gt;
{
    counted2()
    {
        std::cout &lt;&lt; "counted2::counted2()\n";
    }
    ~counted2()
    {
        std::cout &lt;&lt; "counted2::~counted2()\n";
    }
};


int main()
{
    std::cout &lt;&lt; "counted1 [" &lt;&lt; counted1::instances() &lt;&lt; "]\n";
    std::cout &lt;&lt; "counted2 [" &lt;&lt; counted2::instances() &lt;&lt; "]\n";

    counted1 s1;

    std::cout &lt;&lt; "counted1 [" &lt;&lt; counted1::instances() &lt;&lt; "]\n";
    std::cout &lt;&lt; "counted2 [" &lt;&lt; counted2::instances() &lt;&lt; "]\n";

    {
        counted1 s2;
        counted2 s3;

        std::cout &lt;&lt; "counted1 [" &lt;&lt; counted1::instances() &lt;&lt; "]\n";
        std::cout &lt;&lt; "counted2 [" &lt;&lt; counted2::instances() &lt;&lt; "]\n";
    }
    std::cout &lt;&lt; "counted1 [" &lt;&lt; counted1::instances() &lt;&lt; "]\n";
    std::cout &lt;&lt; "counted2 [" &lt;&lt; counted2::instances() &lt;&lt; "]\n";

    return 0;
}


Why did I make the ctors private &amp; not protected? Simply if they were protected every class could inherit from it. Making them private &amp; declaring the template parameter a friend enforces the correct use of the crtp pattern:

struct my_counted_struct : countable&lt;some_other_struct&gt;{};   // error!


This has the side effect that all actual private data (s_counter) is also exposed to the derived class, so this would be possible:

struct my_struct : countable&lt;my_struct&gt;
{
    void do_something_nasty()
    {
        countable&lt;my_struct&gt;::s_counter = 0;
    }
};


That's why the actual private data is in the inner class counter which declares countable a friend, giving it access to its private data.
Nice use of the "Curiously Recurring Template Pattern".

The trouble with your design, is that any user of your class needs to declare their own version of the s_counter. Not strictly a problem but it does make it harder to use.

I would use static function variable as the counter. That way you don't actually need to declare your own version.

    struct counter
    {
        private:
            // Should not be used by friends.
            static std::atomic&lt;uint32_t&gt;&amp; getCounterInstance() {
                static std::atomic&lt;uint32_t&gt;  counter = 0;
                return counter;
            }
    };


As counter is a private member of countable. Nobody else can see it (let alone access it). So you don't need to make countable a friend. Just use some standard public functions to get you accesses.

template&lt;typename t_derived&gt;
class countable
{
    struct counter
    {
        private:
            // Should not be used by friends.
            static std::atomic&lt;uint32_t&gt;&amp; getCounterInstance() {
                static std::atomic&lt;uint32_t&gt;  counter = 0;
                return counter;
            }

       public:
            // Handy access methods:
            static void incrementCounter() {
                ++getCounterInstance();
            }
            static void decrementCounter() {
                --getCounterInstance();
            }
    };
};


The only person that has access to incrementCounter() and decrementCounter() are members of countable.

You got the default constructor and the copy constructor.

    countable()
    {
        ++counter::s_counter;
    }

    countable(const countable&amp;)
    {
        ++counter::s_counter;
    }


But you forgot the move constructor.

    countable(countable&amp;&amp;)
    {
        counter::incrementCounter();
    }