出于自省的目的,有时我想自动将序列号分配给类型或类似的东西。
不幸的是,模板元编程本质上是一种函数式语言,因此缺少实现这种计数器的全局变量或可修改状态。
或者是吗?
请求的示例代码:
#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 10"
}
原文由 Potatoswatter 发布,翻译遵循 CC BY-SA 4.0 许可协议
嗯……是的,模板元编程没有预期的副作用。我被旧版本的 GCC 中的一个错误和标准中的一些不清楚的措辞误导我相信所有这些功能都是可能的。
但是,至少可以在几乎不使用模板的情况下实现命名空间范围的功能。函数查找可以从声明的函数集中提取数字状态,如下所示。
库代码:
快速演示( 看它运行):
C++11 更新
这是使用 C++11
constexpr
代替sizeof
的更新版本。http://ideone.com/yp19oo
声明应该放在命名空间内,并且宏中使用的所有名称除了
counter_crumb
应该是完全限定的。counter_crumb
模板是通过与constant_index
类型的 ADL 关联找到的。COUNTER_LINK_NAMESPACE
宏可用于在多个命名空间范围内增加一个计数器。