https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112288
--- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> --- // PR c++/112288 namespace { template <typename Context, int Start = 0, int Step = 1> class counter { public: template <typename Unique> static constexpr int next() { return next<Unique>(0)*Step+Start; } private: template <int I> struct slot { template <typename Dummy> friend constexpr auto slot_allocated(Dummy, slot<I>); }; template <int I> struct allocate_slot { template <typename Dummy> friend constexpr auto slot_allocated(Dummy, slot<I>) { return true; } enum { value = I }; }; template <typename Unique, int I = 0, int Dummy = 0, bool = slot_allocated(Dummy, slot<I>())> static constexpr int next(int) { return next<Unique, I+1>(0); } template <typename Unique, int I = 0> static constexpr int next(double) { return allocate_slot<I>::value; } }; } template <int I> struct U; struct C: counter<U<1>>{}; int a = C::next<struct unique_1>(); int b = C::next<struct unique_2>();