用于创建结构的可变参数宏
Variadic macro to create struct
我如何编写一个可以像这样使用的宏(用于 gcc):
CREATE_STRUCT(my_struct1,foo);
CREATE_STRUCT(my_struct2,foo,bar);
并扩展到
struct my_struct1 {
std::string foo;
};
struct my_struct2 {
std::string foo;
std::string bar;
};
?
我当然需要不同数量的成员的灵活性,但对我来说已经很少了(大约 4 或 5)。
我发现了几个相关的问题,例如 this and this,但是当我试图将这种神秘的宏魔法应用到这个问题时我完全迷失了。
PS:我知道如何编写 5 个宏(每个参数一个)来完成这项工作,所以实际上问题是:是否有 "easy" 的写法一个可以完成这项工作的可变参数宏?另一方面,我将向结构体中添加更多内容,因此将它们全部放在一个地方可以节省大量样板文件。
使用来自的代码是否可以迭代可变参数宏中的参数?
,
你可以这样做(硬编码最多 8 个参数):
#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2)
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
#define CONCATENATE2(arg1, arg2) arg1##arg2
#define FOR_EACH_1(what, x) what(x);
#define FOR_EACH_2(what, x, ...)\
what(x);\
FOR_EACH_1(what, __VA_ARGS__)
#define FOR_EACH_3(what, x, ...)\
what(x);\
FOR_EACH_2(what, __VA_ARGS__)
#define FOR_EACH_4(what, x, ...)\
what(x);\
FOR_EACH_3(what, __VA_ARGS__)
#define FOR_EACH_5(what, x, ...)\
what(x);\
FOR_EACH_4(what, __VA_ARGS__)
#define FOR_EACH_6(what, x, ...)\
what(x);\
FOR_EACH_5(what, __VA_ARGS__)
#define FOR_EACH_7(what, x, ...)\
what(x);\
FOR_EACH_6(what, __VA_ARGS__)
#define FOR_EACH_8(what, x, ...)\
what(x);\
FOR_EACH_7(what, __VA_ARGS__)
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N())
#define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__)
#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
#define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
#define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__)
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
#define STRING_MEMBERS(x) std::string x
#define CREATE_STRUCT(name, ...) struct name { FOR_EACH(STRING_MEMBERS, __VA_ARGS__) }
CREATE_STRUCT(my_struct1, foo);
CREATE_STRUCT(my_struct2,foo,bar);
这里是简单的实现,限五位成员。
#define CREATE_STRUCT_IMPL_1(S1) std::string S1;
#define CREATE_STRUCT_IMPL_2(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_1(__VA_ARGS__)
#define CREATE_STRUCT_IMPL_3(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_2(__VA_ARGS__)
#define CREATE_STRUCT_IMPL_4(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_3(__VA_ARGS__)
#define CREATE_STRUCT_IMPL_5(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_4(__VA_ARGS__)
#define CREATE_STRUCT_IMPL(_1,_2,_3,_4,_5,NAME,...) NAME
#define CREATE_STRUCT(N, ...) struct N{ CREATE_STRUCT_IMPL(__VA_ARGS__, CREATE_STRUCT_IMPL_5, CREATE_STRUCT_IMPL_4, CREATE_STRUCT_IMPL_3, CREATE_STRUCT_IMPL_2, CREATE_STRUCT_IMPL_1)(__VA_ARGS__) }
例子
CREATE_STRUCT(my_struct1, foo);
CREATE_STRUCT(my_struct2, foo, bar);
CREATE_STRUCT(my_struct3, foo, bar, meow);
CREATE_STRUCT(my_struct4, foo, bar, meow, bazz);
CREATE_STRUCT(my_struct5, foo, bar, meow, bazz, dash);
这适用于任意数量的参数:
#define CREATE_STRUCT(N, ...) struct N { std::string __VA_ARGS__; }
示例:
CREATE_STRUCT(MyStruct, foo);
CREATE_STRUCT(MyStruct, foo, bar);
CREATE_STRUCT(MyStruct, foo, bar, baz);
我如何编写一个可以像这样使用的宏(用于 gcc):
CREATE_STRUCT(my_struct1,foo);
CREATE_STRUCT(my_struct2,foo,bar);
并扩展到
struct my_struct1 {
std::string foo;
};
struct my_struct2 {
std::string foo;
std::string bar;
};
?
我当然需要不同数量的成员的灵活性,但对我来说已经很少了(大约 4 或 5)。
我发现了几个相关的问题,例如 this and this,但是当我试图将这种神秘的宏魔法应用到这个问题时我完全迷失了。
PS:我知道如何编写 5 个宏(每个参数一个)来完成这项工作,所以实际上问题是:是否有 "easy" 的写法一个可以完成这项工作的可变参数宏?另一方面,我将向结构体中添加更多内容,因此将它们全部放在一个地方可以节省大量样板文件。
使用来自的代码是否可以迭代可变参数宏中的参数? , 你可以这样做(硬编码最多 8 个参数):
#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2)
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
#define CONCATENATE2(arg1, arg2) arg1##arg2
#define FOR_EACH_1(what, x) what(x);
#define FOR_EACH_2(what, x, ...)\
what(x);\
FOR_EACH_1(what, __VA_ARGS__)
#define FOR_EACH_3(what, x, ...)\
what(x);\
FOR_EACH_2(what, __VA_ARGS__)
#define FOR_EACH_4(what, x, ...)\
what(x);\
FOR_EACH_3(what, __VA_ARGS__)
#define FOR_EACH_5(what, x, ...)\
what(x);\
FOR_EACH_4(what, __VA_ARGS__)
#define FOR_EACH_6(what, x, ...)\
what(x);\
FOR_EACH_5(what, __VA_ARGS__)
#define FOR_EACH_7(what, x, ...)\
what(x);\
FOR_EACH_6(what, __VA_ARGS__)
#define FOR_EACH_8(what, x, ...)\
what(x);\
FOR_EACH_7(what, __VA_ARGS__)
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N())
#define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__)
#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
#define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
#define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__)
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
#define STRING_MEMBERS(x) std::string x
#define CREATE_STRUCT(name, ...) struct name { FOR_EACH(STRING_MEMBERS, __VA_ARGS__) }
CREATE_STRUCT(my_struct1, foo);
CREATE_STRUCT(my_struct2,foo,bar);
这里是简单的实现,限五位成员。
#define CREATE_STRUCT_IMPL_1(S1) std::string S1;
#define CREATE_STRUCT_IMPL_2(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_1(__VA_ARGS__)
#define CREATE_STRUCT_IMPL_3(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_2(__VA_ARGS__)
#define CREATE_STRUCT_IMPL_4(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_3(__VA_ARGS__)
#define CREATE_STRUCT_IMPL_5(S1, ...) CREATE_STRUCT_IMPL_1(S1) CREATE_STRUCT_IMPL_4(__VA_ARGS__)
#define CREATE_STRUCT_IMPL(_1,_2,_3,_4,_5,NAME,...) NAME
#define CREATE_STRUCT(N, ...) struct N{ CREATE_STRUCT_IMPL(__VA_ARGS__, CREATE_STRUCT_IMPL_5, CREATE_STRUCT_IMPL_4, CREATE_STRUCT_IMPL_3, CREATE_STRUCT_IMPL_2, CREATE_STRUCT_IMPL_1)(__VA_ARGS__) }
例子
CREATE_STRUCT(my_struct1, foo);
CREATE_STRUCT(my_struct2, foo, bar);
CREATE_STRUCT(my_struct3, foo, bar, meow);
CREATE_STRUCT(my_struct4, foo, bar, meow, bazz);
CREATE_STRUCT(my_struct5, foo, bar, meow, bazz, dash);
这适用于任意数量的参数:
#define CREATE_STRUCT(N, ...) struct N { std::string __VA_ARGS__; }
示例:
CREATE_STRUCT(MyStruct, foo);
CREATE_STRUCT(MyStruct, foo, bar);
CREATE_STRUCT(MyStruct, foo, bar, baz);