我目前正在使用C库代码中的__COUNTER__
宏来生成唯一的整数标识符。它工作得很好,但我看到两个问题:
__COUNTER__
的独立代码可能会感到困惑。因此,我希望自己实现等同于__COUNTER__
。
我知道的替代品,但不想要使用:
__LINE__
(因为每行多个宏不会获得唯一ID)BOOST_PP_COUNTER
(因为我不想要boost
依赖项) BOOST_PP_COUNTER
证明可以做到这一点,即使other答案声称这是不可能的。
本质上,我正在寻找一个头文件“mycounter.h”,这样
#include "mycounter.h"
__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
将由gcc -E
预处理
(...)
0
1 2
3
不使用内置__COUNTER__
。
注意:此前,此问题被标记为this的副本,该问题涉及使用__COUNTER__
而不是避免使用它。
答案 0 :(得分:3)
您无法直接实施__COUNTER__
。预处理器纯粹是功能性的 - 没有状态变化。在这样的系统中,隐藏的计数器本身是不可能的。 (BOOST_PP_COUNTER
您可以做的是重构您的元程序,以便计数器可以通过纯函数应用于输入数据。例如使用好的'Order:
#include
(递减列表,将子列表元素保留在原来的位置,并用__LINE__
替换非列表元素 - 用递增的计数器变量替换)
我假设您实际上并不想简单地在程序顶层删除#include <order/interpreter.h>
#define ORDER_PP_DEF_8map_count \
ORDER_PP_FN(8fn(8L, 8rec_mc(8L, 8nil, 0)))
#define ORDER_PP_DEF_8rec_mc \
ORDER_PP_FN(8fn(8L, 8R, 8C, \
8if(8is_nil(8L), \
8R, \
8let((8H, 8seq_head(8L)) \
(8T, 8seq_tail(8L)) \
(8D, 8plus(8C, 1)), \
8if(8is_seq(8H), \
8rec_mc(8T, 8seq_append(8R, 8seq_take(1, 8L)), 8C), \
8rec_mc(8T, 8seq_append(8R, 8seq(8C)), 8D) )))))
ORDER_PP (
8map_count(8seq( 8seq(8(A)), 8true, 8seq(8(C)), 8true, 8true )) //((A))(0)((C))(1)(2)
)
值,因此如果您可以将需要编码的代码放在一个包装宏中的8false
值内然后,您可以将列表提供给类似于示例的纯函数。
当然,能够表达此类代码的元编程库将比__COUNTER__
显着更不便于携带和维护。 __COUNTER__
由英特尔,GCC,Clang和MSVC提供支持。 (不是每个人,例如__COUNTER__
都没有它,但是有人甚至没有使用它吗?)可以说,如果你在实际代码中展示了这个特性,那么标准化委员会就会{{1} } 应该成为下一个C标准的一部分。
答案 1 :(得分:2)
你混淆了两件事:
1 - 处理#define
和#include
之类的东西的预处理器。它仅作为文本(意思是字符序列)级别起作用,并且具有很少的计算能力。它非常有限,无法实现__COUNTER__
。预处理器工作仅包括宏扩展和文件替换。关键是它在之前发生编译甚至开始。
2 - C ++语言,特别是模板(元)编程语言,可用于在编译阶段计算内容。它确实是完整的,但正如我已经说过预处理后的编译开始。
所以你要问的是在标准C或C ++中不可行。为了解决这个问题,boost
实现了自己的预处理器,它不符合标准并具有更多的计算能力。特别是可以使用它来构建__counter__
的类似物。
答案 2 :(得分:-1)
This small header of mine包含一个自己的C预处理器计数器实现(它使用稍微不同的语法)。