如何减少 xmacro table 扩展中的数字参数
How to reduce number arguments in xmacro table expansion
我一直在使用基于 xmacros 的 tables:
#define TABLE_MACRO(MAN_TYPE, WOMAN_TYPE) \
MAN_TYPE( John, Doe, "Addr1", arg_a, arg_b, arg_c) \
WOMAN_TYPE( Jane, Joe, "Addr2", arg_a, arg_b, arg_c) \
MAN_TYPE( Bill, Tom, "Addr3", arg_a, arg_b, arg_c) \
我有 tables 的参数比我展示的要多得多,但是,在许多情况下,我只是将 table 扩展为 1 或 2。我使用它们来生成变量和枚举。例如:
#define NAME_LIST(name,last,addr, arg1, arg2, arg3) name,\
enum {
TABLE_MACRO(NAME_LIST,NAME_LIST)
}Name_List;
有没有办法采用 TABLE_MACRO 并重新定义或更改它的扩展顺序以扩展到这个?
TABLE_MACRO_NAMES_ONLY(MAN_TYPE, WOMAN_TYPE) \
MAN_TYPE( John, ) \
WOMAN_TYPE( Jane, ) \
MAN_TYPE( Bill, ) \
我的目标是简化 tables,像这样使用:
#define NEW_NAME(name) New_##name,
TABLE_MACRO_NAMES_ONLY(NEW_NAME, NEW_NAME)
希望等待得到回报:
我想出了两个解决方案。一种可以保持原来的table不变,但是使用起来有点不方便。
解决方案 1
// your original table as is
#define TABLE_MACRO(MAN_TYPE, WOMAN_TYPE) \
MAN_TYPE( John, Doe, "Addr1", arg_a, arg_b, arg_c) \
WOMAN_TYPE( Jane, Joe, "Addr2", arg_a, arg_b, arg_c) \
MAN_TYPE( Bill, Tom, "Addr3", arg_a, arg_b, arg_c) \
// create Names only table
#define MTYPE(a,b,c,d,e,f) MAN(a)
#define WTYPE(a,b,c,d,e,f) WOMAN(a)
#define TABLE_NAMES_ONLY \
TABLE_MACRO(MTYPE,WTYPE)
// usage (here, the defines MUST be named "MAN" and "WOMAN".
// At least they have to align with the definition of MTYPE and WTYPE)
#define MAN(name) man_##name
#define WOMAN(name) woman_##name
TABLE_NAMES_ONLY
另一种解决方案涉及将原始 table 扩展两个参数,但最终使用起来更容易。
解决方案 2
// your extended original table (see extra arguments)
#define TABLE_MACRO(MAN_TYPE, WOMAN_TYPE, m_extra, w_extra) \
MAN_TYPE( John, Doe, "Addr1", arg_a, arg_b, arg_c, m_extra, w_extra) \
WOMAN_TYPE( Jane, Joe, "Addr2", arg_a, arg_b, arg_c, m_extra, w_extra) \
MAN_TYPE( Bill, Tom, "Addr3", arg_a, arg_b, arg_c, m_extra, w_extra) \
// create Names only table
#define MTYPE(a,b,c,d,e,f, m_extra, w_extra) m_extra(a)
#define WTYPE(a,b,c,d,e,f, m_extra, w_extra) w_extra(a)
#define TABLE_NAMES_ONLY(male_func, female_func) \
TABLE_MACRO(MTYPE, WTYPE, male_func, female_func)
// usage (here, the naming of the 2 following defines is arbitrary)
#define MAN(a) man_##a
#define WOMAN(a) woman_##a
TABLE_NAMES_ONLY(MAN, WOMAN)
// different usage:
#define NAME(a) name_##a
TABLE_NAMES_ONLY(NAME, NAME)
两种解决方案均已使用 gcc -E yourTestFile.c
通过 gcc 5.3.0 进行了测试。
可能有更好的解决方案,但这些是我想到的。
我一直在使用基于 xmacros 的 tables:
#define TABLE_MACRO(MAN_TYPE, WOMAN_TYPE) \
MAN_TYPE( John, Doe, "Addr1", arg_a, arg_b, arg_c) \
WOMAN_TYPE( Jane, Joe, "Addr2", arg_a, arg_b, arg_c) \
MAN_TYPE( Bill, Tom, "Addr3", arg_a, arg_b, arg_c) \
我有 tables 的参数比我展示的要多得多,但是,在许多情况下,我只是将 table 扩展为 1 或 2。我使用它们来生成变量和枚举。例如:
#define NAME_LIST(name,last,addr, arg1, arg2, arg3) name,\
enum {
TABLE_MACRO(NAME_LIST,NAME_LIST)
}Name_List;
有没有办法采用 TABLE_MACRO 并重新定义或更改它的扩展顺序以扩展到这个?
TABLE_MACRO_NAMES_ONLY(MAN_TYPE, WOMAN_TYPE) \
MAN_TYPE( John, ) \
WOMAN_TYPE( Jane, ) \
MAN_TYPE( Bill, ) \
我的目标是简化 tables,像这样使用:
#define NEW_NAME(name) New_##name,
TABLE_MACRO_NAMES_ONLY(NEW_NAME, NEW_NAME)
希望等待得到回报:
我想出了两个解决方案。一种可以保持原来的table不变,但是使用起来有点不方便。
解决方案 1
// your original table as is
#define TABLE_MACRO(MAN_TYPE, WOMAN_TYPE) \
MAN_TYPE( John, Doe, "Addr1", arg_a, arg_b, arg_c) \
WOMAN_TYPE( Jane, Joe, "Addr2", arg_a, arg_b, arg_c) \
MAN_TYPE( Bill, Tom, "Addr3", arg_a, arg_b, arg_c) \
// create Names only table
#define MTYPE(a,b,c,d,e,f) MAN(a)
#define WTYPE(a,b,c,d,e,f) WOMAN(a)
#define TABLE_NAMES_ONLY \
TABLE_MACRO(MTYPE,WTYPE)
// usage (here, the defines MUST be named "MAN" and "WOMAN".
// At least they have to align with the definition of MTYPE and WTYPE)
#define MAN(name) man_##name
#define WOMAN(name) woman_##name
TABLE_NAMES_ONLY
另一种解决方案涉及将原始 table 扩展两个参数,但最终使用起来更容易。
解决方案 2
// your extended original table (see extra arguments)
#define TABLE_MACRO(MAN_TYPE, WOMAN_TYPE, m_extra, w_extra) \
MAN_TYPE( John, Doe, "Addr1", arg_a, arg_b, arg_c, m_extra, w_extra) \
WOMAN_TYPE( Jane, Joe, "Addr2", arg_a, arg_b, arg_c, m_extra, w_extra) \
MAN_TYPE( Bill, Tom, "Addr3", arg_a, arg_b, arg_c, m_extra, w_extra) \
// create Names only table
#define MTYPE(a,b,c,d,e,f, m_extra, w_extra) m_extra(a)
#define WTYPE(a,b,c,d,e,f, m_extra, w_extra) w_extra(a)
#define TABLE_NAMES_ONLY(male_func, female_func) \
TABLE_MACRO(MTYPE, WTYPE, male_func, female_func)
// usage (here, the naming of the 2 following defines is arbitrary)
#define MAN(a) man_##a
#define WOMAN(a) woman_##a
TABLE_NAMES_ONLY(MAN, WOMAN)
// different usage:
#define NAME(a) name_##a
TABLE_NAMES_ONLY(NAME, NAME)
两种解决方案均已使用 gcc -E yourTestFile.c
通过 gcc 5.3.0 进行了测试。
可能有更好的解决方案,但这些是我想到的。