我想知道是否有可能在宏参数上编写宏foreach.这是想做的事情:
#define PRINT(a) printf(#a": %d", a)
#define PRINT_ALL(...) ? ? ? THE PROBLEM ? ? ?
Run Code Online (Sandbox Code Playgroud)
可能的用法:
int a = 1, b = 3, d = 0;
PRINT_ALL(a,b,d);
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所取得的成就
#define FIRST_ARG(arg,...) arg
#define AFTER_FIRST_ARG(arg,...) , ##__VA_ARGS__
#define PRINT(a) printf(#a": %d", a)
#define PRINT_ALL PRINT(FIRST_ARG(__VA_ARGS__)); PRINT_ALL(AFTER_FIRST_ARG(__VA_ARGS__))
Run Code Online (Sandbox Code Playgroud)
这是一个递归宏,这是非法的.另一个问题是stop condition递归.
*不要与与关联阵列有任何关系混淆.
我知道如何使用宏来向量化C中的函数,以提供类似于Mathematica的Map(或Apply)功能的结果.即将函数应用于参数列表.
#define Apply( type, function, ...) \
{ \
void *Stop = (int[]){0}; \
type **List = (type*[]){__VA_ARGS__, Stop}; \
for( int i = 0; List[i] != Stop; ++i ) \
function( List[i] ); \
}
Run Code Online (Sandbox Code Playgroud)
然后我可以做类似的事情
#define FreeAllAtOnce(...) Apply( void, free, __VA_ARGS__ );
Run Code Online (Sandbox Code Playgroud)
这有效果
free( Array1 );
free( Array2 );
free( Array3 );
Run Code Online (Sandbox Code Playgroud)
相当于
FreeAllAtOnce( Array1, Array2, Array3 );
Run Code Online (Sandbox Code Playgroud)
我没有说明这一点,我在一本书中读到了它并且从那以后大量使用它.
我的问题是:我可以做类似的事情通过一些二进制函数关联组合一个数组.例如,采用GCD功能.我想要一个像这样的功能:
GCD_all( a, b, c, d, e );
Run Code Online (Sandbox Code Playgroud)
这与效果相同
GCD( GCD( GCD( GCD( a, b ), c …Run Code Online (Sandbox Code Playgroud) 是否可以定义BUILD(a, i)扩展为" x[0], x[1], x[2], ..., x[i]" 的C/C++宏" "?像
#define BUILD(x, 0) x[0]
#define BUILD(x, 1) x[0], x[1]
#define BUILD(x, 2) x[0], x[1], x[2]
...
Run Code Online (Sandbox Code Playgroud)
似乎BOOST_PP_ENUM_PARAMS可以完成这项工作.我想我可以#include boost,但我很想知道它是如何以及为什么有效,任何人都可以解释一下?
我想调用一个带有f(int, ...)N个int参数的函数x[i],0 <= i <N.其中N已知ceil(sizeof(A) / sizeof(B)).所以不幸的是,我不能使用varargs或模板.
我正在尝试使用 C++11 可变宏。
我试图对列表中的每个参数应用另一个宏。
这是我的第一次尝试:
#define APPLY_CHAIN(first, ...) APPLY_ACT(first) APPLY_CHAIN( __VA_ARGS__ )
Run Code Online (Sandbox Code Playgroud)
不幸的是这没有用。
我最终让它发挥作用。但它有点复杂,并且有“n”的限制(其中“n”是我愿意为其键入宏的最大大小)。
#define COUNT_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define COUNT(...) COUNT_N( __VA_ARGS__, 10, 9, 8, 7, 6, 5 ,4, 3, 2, 1)
#define BUILD_CHAIN_1(_1) APPLY_ACT(_1)
#define BUILD_CHAIN_2(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_1(__VA_ARGS__)
#define BUILD_CHAIN_3(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_2(__VA_ARGS__)
#define BUILD_CHAIN_4(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_3(__VA_ARGS__)
#define BUILD_CHAIN_5(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_4(__VA_ARGS__)
#define BUILD_CHAIN_6(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_5(__VA_ARGS__)
#define BUILD_CHAIN_7(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_6(__VA_ARGS__)
#define BUILD_CHAIN_8(_1, ...) APPLY_ACT(_1) BUILD_CHAIN_7(__VA_ARGS__) …Run Code Online (Sandbox Code Playgroud) 我想要一个接受多个函数指针的宏调用,并且每个函数指针由第二个宏调用,该宏是函数声明。
我想要表单上的两个宏
#define FUNCTION_DEF(func) extern int func(void);
#define FUNCTION_DEFS(...) (???)
Run Code Online (Sandbox Code Playgroud)
这就是所谓的
FUNCTION_DEFS(
myFunc1,
myFunc2,
otherFunc1,
otherFunc2,
defaultFunc
)
Run Code Online (Sandbox Code Playgroud)
扩展到
FUNCTION_DEF(myFunc1)
FUNCTION_DEF(myFunc2)
FUNCTION_DEF(otherFunc1)
FUNCTION_DEF(otherFunc2)
FUNCTION_DEF(defaultFunc)
Run Code Online (Sandbox Code Playgroud)
换句话说,这个单一调用FUNCTION_DEFS扩展到所有可变参数的函数声明。
目前,我只是跳过第一步并调用FUNCTION_DEF每个函数指针,但是对此的解决方案会很棒。
这可能吗?
感谢 @Vality 向我介绍 X-Macro。我发现这篇文章“ Real-world use of X-Macros ”正是我所需要的。
我想创建一个宏来定义一个在对象列表上调用该函数的函数.它不一定必须是预处理器宏,但它应该工作.
我想写这样的东西:
CALL_ON_ALL(doSomething(int arg1, bool arg2))
Run Code Online (Sandbox Code Playgroud)
我想要它产生这个:
void doSomething(int arg1, bool arg2) {
for (int i = 0; i < delegates.size(); i++)
delegates[i]->doSomething(arg1, arg2);
}
Run Code Online (Sandbox Code Playgroud)
我有一些有用的东西:
#define CALL_ON_ALL(defSig, callSig) \
void defSig { \
for (int i = 0; i < delegates.size(); i++) \
delegates[i]->callSig; \
}
Run Code Online (Sandbox Code Playgroud)
问题是我必须分别编写定义签名和调用签名,如下所示:
CALL_ON_ALL(doSomething(int arg1, bool arg2), doSomething(arg1, arg2))
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?
它不一定必须是预处理器宏.任何有效的方法都可以.