在编译时生成唯一的数字

hel*_*ami 8 c++ metaprogramming side-effects compile-time c++11

我想为我的标题中的每个类生成唯一的数字,在我的案例中为素数,但是假设这应该只是连续的数字,即1,2,3,4等.

当然我可以硬编码:

struct A { enum { ID = 1; }; };
struct B { enum { ID = 2; }; };
struct C { enum { ID = 3; }; };
struct D { enum { ID = 4; }; };
Run Code Online (Sandbox Code Playgroud)

这非常容易出错,因为实际上类不是那么小,如果我在中间添加一个新类,如果我不想完全忽略ID的概述,我必须更改以下所有数字.

我希望我能做到以下几点:

struct A { enum { ID = get_next_int(); }; };
struct B { enum { ID = get_next_int(); }; };
struct C { enum { ID = get_next_int(); }; };
struct D { enum { ID = get_next_int(); }; };
Run Code Online (Sandbox Code Playgroud)

但由于constexpr函数调用不能产生副作用,这是不可能的.我认为使用宏这样的结果也是不可能的.

我也很幸运,有这样的事情:

struct A_id_holder : some_base_counter {};
struct A { enum { ID = A_id_holder::ID; }; };

struct B_id_holder : some_base_counter {};
struct B { enum { ID = B_id_holder::ID; }; };

struct C_id_holder : some_base_counter {};
struct C { enum { ID = C_id_holder::ID; }; };

struct D_id_holder : some_base_counter {};
struct D { enum { ID = D_id_holder::ID; }; };
Run Code Online (Sandbox Code Playgroud)

但老实说,我不知道如何实现这一点.

我可以实现我的目标,如果是,怎么样?

Pot*_*ter 3

大多数人用__COUNTER__宏来做到这一点。但这是非标准的,而且整个程序只有一个。

这是我使用模板和重载提出的C++ hack,它符合标准并支持多个计数器。