出于内省的目的,有时我想自动为类型或类似的东西分配序列号.
不幸的是,模板元编程本质上是一种功能语言,因此缺乏实现这种计数器的全局变量或可修改状态.
或者是吗?
按请求的示例代码:
#include <iostream>
int const a = counter_read;
counter_inc;
counter_inc;
counter_inc;
counter_inc;
counter_inc;
int const b = counter_read;
int main() {
std::cout << a << ' ' << b << '\n'; // print "0 5"
counter_inc_t();
counter_inc_t();
counter_inc_t();
std::cout << counter_read << '\n'; // print "8"
struct {
counter_inc_t d1;
char x[ counter_read ];
counter_inc_t d2;
char y[ counter_read ];
} ls;
std::cout << sizeof ls.x << ' ' << sizeof ls.y << '\n'; // print "9 …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习一些神秘的有状态模板元编程技巧。
(这就是我想学习它的原因。不幸的是,这个库在 GCC 8 和 Clang 上都不起作用。)
我需要的第一个明显的东西是一个constexpr计数器:
/*something*/ constexpr int foo() /*something*/
int main()
{
constexpr int a = foo();
constexpr int b = foo();
constexpr int c = foo();
static_assert(a == 0 && b == 1 && c == 2);
}
Run Code Online (Sandbox Code Playgroud)
最好它应该是一个标记的计数器,以便我可以同时拥有多个计数器:
/*something*/ constexpr int foo() /*something*/
struct TagA {};
struct TagB {};
int main()
{
constexpr int a = foo<TagA>();
constexpr int b = foo<TagA>();
constexpr int c = foo<TagA>();
constexpr …Run Code Online (Sandbox Code Playgroud) 我有一个编译时计数器,我使用多年,受这些答案的启发.它适用于C++ 03/11,就我测试而言,在主要编译器上相对较好:
namespace meta
{
template<unsigned int n> struct Count { char data[n]; };
template<int n> struct ICount : public ICount<n-1> {};
template<> struct ICount<0> {};
#define MAX_COUNT 64
#define MAKE_COUNTER( _tag_ ) \
static ::meta::Count<1> _counter ## _tag_ (::meta::ICount<1>)
#define GET_COUNT( _tag_ ) \
(sizeof(_counter ## _tag_ (::meta::ICount<MAX_COUNT + 1>())) - 1)
#define INC_COUNT( _tag_ ) \
static ::meta::Count<GET_COUNT(_tag_) + 2> _counter ## _tag_ (::meta::ICount<2 + GET_COUNT(_tag_)>)
}
Run Code Online (Sandbox Code Playgroud)
以下测试编译并运行完美(预期输出为0 1 2 3):
struct …Run Code Online (Sandbox Code Playgroud)