C预处理器:计数器的自身实现__
我目前正在使用C库代码中的C预处理器:计数器的自身实现__,c,macros,c-preprocessor,C,Macros,C Preprocessor,我目前正在使用C库代码中的\uuu计数器\uuu宏来生成唯一的整数标识符。它工作得很好,但我看到两个问题: 它不是任何C或C++标准的一部分。 同时使用\uuuu计数器的独立代码可能会混淆 因此,我希望自己实现一个与\uuuu计数器等效的计数器 我知道但不想使用的备选方案: \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(因为每行多个宏不会获得唯一的ID BOOST\u PP\u计数器(因为我不想要BOOST依赖
\uuu计数器\uuu
宏来生成唯一的整数标识符。它工作得很好,但我看到两个问题:
- 同时使用
\uuuu计数器的独立代码可能会混淆
\uuuu计数器
等效的计数器
我知道但不想使用的备选方案:
(因为每行多个宏不会获得唯一的ID\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
(因为我不想要BOOST\u PP\u计数器
依赖项)BOOST
BOOST\u PP\u计数器
证明了这是可以做到的,尽管答案声称这是不可能的
本质上,我正在寻找一个头文件“mycounter.h”,这样
#include "mycounter.h"
__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
将由gcc-E
预处理到
(...)
0
1 2
3
不使用内置的计数器
注意:前面,这个问题被标记为的副本,它涉及使用
\uuuu计数器\uuuuu>而不是避免它。您混淆了两件不同的事情:
1-处理#定义和#包含类似内容的预处理器。它只在文本(意味着字符序列)级别工作,并且具有很少的计算能力。它非常有限,无法实现\uuuu计数器\uuu
。预处理器的工作仅包括宏扩展和文件替换。关键的一点是它发生在编译开始之前
2——C++语言,特别是模板(元)编程语言,它可以用于编译阶段的计算。它确实是图灵完成的,但正如我已经说过的,编译是在预处理之后开始的
<> P>所以你所要求的是标准C或C++中不可行的。为了解决这个问题,boost实现了它自己的预处理器,它不符合标准,并且具有更多的计算能力。特别是,可以使用它构建一个模拟的\uuuu计数器 您不能直接实现\uuuu计数器
。预处理器完全是功能性的,没有状态变化。在这样一个系统中,隐藏计数器本质上是不可能的。(BOOST\u PP\u COUNTER
并不能证明您想要做什么-它依赖于#include
,因此每行只有一个计数器-也可以使用(line)
。也就是说,实现非常出色,您无论如何都应该阅读它。)
您可以做的是重构元程序,以便计数器可以通过纯函数应用于输入数据。e、 g.使用良好的ol':
#包括
#定义订单数量\
订单号(8fn(8L,8rec_mc(8L,8nil,0)))
#定义订单\u PP\u DEF\u 8rec\u mc\
订单(8fn)(8L,8R,8C,\
8if(8is_nil(8L)\
8R\
8let((8H,8seq_头(8L))\
(8T,8seq_尾部(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)())(8T,8seq(8C))
订单号(
8映射计数(8序列(8(A)),8真,8序列(8(C)),8真,8真))/(A))(0)(C))(1)(2)
)
(沿列表向下递归,保留子列表元素,并用递增的计数器变量替换非列表元素(由8false
表示)
我假设您实际上不想简单地将\uuuuu COUNTER\uuuu
值放在程序顶层,因此如果您可以将需要编织\uuu COUNTER\uuuu
值的代码放在包装器宏中,该宏将其拆分为某种序列或列表,那么您可以将该列表提供给一个类似于示例的纯函数
当然,与\uuu COUNTER\uu
相比,能够表达此类代码的元编程库的可移植性和可维护性要低得多<代码>\uuuu计数器
受Intel、GCC、Clang和MSVC支持。(不是每个人都有,例如,pcc
没有,但有人使用过吗?)可以说,如果你在实际代码中演示了正在使用的功能,它向标准化委员会提出了一个更有力的理由,即\uuuu COUNTER\uuuu
应该成为下一个C标准的一部分。包含了一个C预处理器计数器的实现(它使用了稍微不同的语法)。我完全了解CPP和模板元编程之间的区别。为了消除混淆,我重新命名了这个问题。正如我在问题中提到的,这里讨论的:,CPP是图灵完全的,所以它肯定能够做到这一点。Boost甚至实现了它(使用标准CPP)很抱歉,但是你的问题是太模糊了。你想生成什么?不同的字符串?不同的变量?我解释说你不能生成宏。谢谢,我已经更新了这个问题,希望现在能更清楚。注意C和C++预处理器可以在常数i上执行算术。nteger表达式和条件指令。说预处理器工作只包括宏扩展和文件包含是不准确的。@mic_e我想你错过了关于“请注意,需要一个外部构建脚本将预处理器的输出反馈到其输入中,因此预处理器本身并不是图灵完整的。”听起来Boost做了类似的事情,所以您的选项是(1)使用Boost,或者(2)自己重新实现。在某些情况下,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
可能是\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#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)
)