我想知道是否有可能迭代传递给C99中的可变参数宏或使用任何GCC扩展的参数?
例如,是否可以编写一个通用的宏,它接受一个结构,并将其字段作为参数传递,并打印结构中每个字段的偏移量?
像这样的东西:
struct a {
int a;
int b;
int c;
};
/* PRN_STRUCT_OFFSETS will print offset of each of the fields
within structure passed as the first argument.
*/
int main(int argc, char *argv[])
{
PRN_STRUCT_OFFSETS(struct a, a, b, c);
return 0;
}
作为问题的一个例子,有没有办法partialconcat在下面的代码中实现宏?
#define apply(f, x) f(x)
apply(partialconcat(he),llo) //should produce hello
Run Code Online (Sandbox Code Playgroud)
编辑:
这是另一个例子,给定一个FOR_EACH可变参数宏(参见另一个问题的答案中的示例实现).
假设我想在几个对象上调用一个成员,可能在另一个宏中用于更大的目的.我想要一个宏callAmber,其行为如下:
FOR_EACH(callMember(someMemberFunction), a, b, c);
Run Code Online (Sandbox Code Playgroud)
产生
a.someMemberFunction(); b.someMemberFunction(); c.someMemberFunction();
Run Code Online (Sandbox Code Playgroud)
这需要callMember(someMember)产生一个行为像的宏
#define callMember_someMember(o) o.someMember()
Run Code Online (Sandbox Code Playgroud) 我想为可变参数宏中的每个元素追加一个字符串化的宏参数.我想我知道我需要什么,但我还没有想出一个有效的解决方案.给出一个可变宏,如:
#define FIELD_DECLARATION(NAME, OTHER_FIELD, ...)
FIELD_DECLARATION(First, Thing)
FIELD_DECLARATION(Second, Thing, Thing, Nothing)
Run Code Online (Sandbox Code Playgroud)
我想生成:
field_First = {ThingArg};
field_Second = {ThingArg, ThingArg, NothingArg};
Run Code Online (Sandbox Code Playgroud)
我想我需要的是递归地继续扩展__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)
Run Code Online (Sandbox Code Playgroud)
虽然这有点奏效,但我无法提出可扩展的解决方案.如果有人可以放光,那就太棒了.