gpt4 book ai didi

c - 预处理器 : Concatenate string to each argument in __VA_ARGS__

转载 作者:太空狗 更新时间:2023-10-29 16:00:51 24 4
gpt4 key购买 nike

我想将一个字符串化的宏参数附加到可变参数宏中的每个元素。我想我知道我需要什么,但我还不能想出一个可行的解决方案。给定一个可变参数宏,例如:

#define FIELD_DECLARATION(NAME, OTHER_FIELD, ...)

FIELD_DECLARATION(First, Thing)
FIELD_DECLARATION(Second, Thing, Thing, Nothing)

我想生成:

field_First = {ThingArg};
field_Second = {ThingArg, ThingArg, NothingArg};

我想我需要的是递归地扩展 __VA_ARGS__ 直到没有元素,并在扩展时附加 "Arg" 。最后,将结果传递给另一个生成逗号分隔参数列表的可变参数宏。

我已经试过了,但行不通(这也不是我描述的那样):

#define UNPACK_VA_1(A1) A1 ## Arg
#define UNPACK_VA_2(A1, A2) UNPACK_VA_1(A1), UNPACK_VA_1(A2)
#define UNPACK_VA_3(A1, A2, A3) UNPACK_VA_2(A1, A2), UNPACK_VA_1(A3)
#define UNPACK_VA_4(A1, A2, A3, A4) UNPACK_VA_2(A1, A2), UNPACK_VA_2(A3, A4)
#define UNPACK_VA(...) UNPACK_VA_4(__VA_ARGS__)

#define FOO(x, y, ...) UNPACK_VA(__VA_ARGS__)
FOO(One, Two, Three, Four, Five, Six)

虽然这有点管用,但我想不出一个可扩展的解决方案。如果有人能阐明这一点,那就太好了。

最佳答案

这是一种可扩展的方法。首先,一些通用的实用宏:

#define EVAL(...) __VA_ARGS__
#define VARCOUNT(...) \
EVAL(VARCOUNT_I(__VA_ARGS__,9,8,7,6,5,4,3,2,1,))
#define VARCOUNT_I(_,_9,_8,_7,_6,_5,_4,_3,_2,X_,...) X_
#define GLUE(X,Y) GLUE_I(X,Y)
#define GLUE_I(X,Y) X##Y
#define FIRST(...) EVAL(FIRST_I(__VA_ARGS__,))
#define FIRST_I(X,...) X
#define TUPLE_TAIL(...) EVAL(TUPLE_TAIL_I(__VA_ARGS__))
#define TUPLE_TAIL_I(X,...) (__VA_ARGS__)

#define TRANSFORM(NAME_, ARGS_) (GLUE(TRANSFORM_,VARCOUNT ARGS_)(NAME_, ARGS_))
#define TRANSFORM_1(NAME_, ARGS_) NAME_ ARGS_
#define TRANSFORM_2(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_1(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_3(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_2(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_4(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_3(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_5(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_4(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_6(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_5(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_7(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_6(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_8(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_7(NAME_,TUPLE_TAIL ARGS_)
#define TRANSFORM_9(NAME_, ARGS_) NAME_(FIRST ARGS_),TRANSFORM_8(NAME_,TUPLE_TAIL ARGS_)

语义上,VARCOUNT 计算参数; GLUE是典型的间接粘贴; FIRST 提取第一个参数; EVAL 扩展到它的参数(意图求值),TUPLE_TAIL 返回元组的尾部(即,它丢弃第一个参数)。

TRANSFORM 这里是主要思想; TRANSFORM(FOO,(X,Y,Z)) 接受元组 (X,Y,Z)(FOO(X),FOO(Y) ,FOO(Z)).

到位了,这里是特殊用途的代码:

#define Z_ARG(X) GLUE(X,Arg)
#define MAKE_INITIALIZER(...) { __VA_ARGS__ }
#define FIELD_DECLARATION(FNAME_, ...) \
GLUE(field_, FNAME_) = EVAL(MAKE_INITIALIZER TRANSFORM(Z_ARG, (__VA_ARGS__)));

鉴于以上,这应该是可读的,但只是为了解释...... Z_ARGArg 粘贴到一个项目; MAKE_INITIALIZER 将预处理器元组转换为初始化列表; FIELD_DECLARATION 是您的宏。请注意,EVAL 包装了 MAKE_INITIALIZER/转换后的元组,因此它实际上会调用该宏。

注意:将 EVAL 移到顶部并在更多地方使用它,这样它也可以在 MSVC 中使用。

Demonstration, original code

Demonstration, current code

关于c - 预处理器 : Concatenate string to each argument in __VA_ARGS__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44479282/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com