如何在 C++ 预处理器中解析由空格分隔的标记?

问题描述 投票:0回答:1

我正在做一些预处理器元编程,我需要一种方法在 C++ 预处理器中将

f(a b)
转换为
g(a,b)
。由于
a
b
C++
中的两个标记,因此似乎可以找到一种方法将它们分开。然而,经过几个小时的工作,这个问题仍然没有解决方案。

包括

boost::preprocessor
在内的任何第三方库都是受欢迎的,因为这些库在预处理过程中工作。

另外,有什么办法可以分离任意的token吗?例如

const T&
应转换为
const
,
T
,
&

c++ c-preprocessor preprocessor-meta-program
1个回答
0
投票

这是不可能的

对于有限数量的令牌,这是可能的,但你必须有一个字典,包含你想要处理的所有可能的令牌。整个过程在用宏中的下划线替换空格?在这里我将重写它而不只是为了好玩。

通常,您可以将列表的前面与像

WORD_##__VA_ARGS__
这样的前缀连接起来,其中
__VA_ARGS__="a b c"
。然后有了
#define WORD_a a,
,您可以将前导词与其余词分开。对每个令牌重复此过程,您可以创建一个单独的令牌列表。

// dictionary of all words
#define WORD_
#define WORD_a a,
#define WORD_b b,
#define WORD_c c,
#define WORD_d d,

#define TOKENIZE_1(a)      WORD_##a
#define TOKENIZE_2(a,...)  a, TOKENIZE_1(__VA_ARGS__)
#define TOKENIZE_3(a,...)  a, TOKENIZE_2(__VA_ARGS__)
#define TOKENIZE_4(a,...)  a, TOKENIZE_3(__VA_ARGS__)
#define TOKENIZE_5(a,...)  a, TOKENIZE_4(__VA_ARGS__)
#define TOKENIZE_N(_5,_4,_3,_2,_1,N,...)  TOKENIZE##N
#define TOKENIZE(...)  TOKENIZE_N(__VA_ARGS__,_5,_4,_3,_2,_1)(__VA_ARGS__)

#define REMOVELAST_1(a)
#define REMOVELAST_2(a,...)  a
#define REMOVELAST_3(a,...)  a, REMOVELAST_2(__VA_ARGS__)
#define REMOVELAST_4(a,...)  a, REMOVELAST_3(__VA_ARGS__)
#define REMOVELAST_5(a,...)  a, REMOVELAST_4(__VA_ARGS__)
#define REMOVELAST_N(_5,_4,_3,_2,_1,N,...) REMOVELAST##N
#define REMOVELAST(...)  REMOVELAST_N(__VA_ARGS__,_5,_4,_3,_2,_1)(__VA_ARGS__)

#define SPACES_TO_ARGS(...)  REMOVELAST(TOKENIZE(TOKENIZE(TOKENIZE(TOKENIZE(__VA_ARGS__)))))

#define f(spaceargs)  g(SPACES_TO_ARGS(spaceargs))

f(a b) to g(a, b)
f(a b c) to g(a, b, c)
f(a b c d) to g(a, b, c, d)

另外,有什么办法可以分离任意的token吗?

不,那是不可能的

© www.soinside.com 2019 - 2024. All rights reserved.