如何为TRY_IT宏添加第二个可变参数列表(__VA_ARGS__)?
如何为TRY_IT宏添加第二个可变参数列表(VA_ARGS)?
嘿,我懂你想让这个TRY_IT宏支持带可变参数的函数调用的需求,这事儿其实很容易调整,咱们一步步来改就行。
首先看你原来的宏,问题出在调用func的时候是硬写成(func)()——完全没留参数传递的口子。要让func能接收可变参数,咱们只需要给宏加上可变参数的支持,然后把这些参数传递给func就行。
这里给你修改后的完整宏定义,我还补全了你原来没写完的逻辑(比如重试到上限时触发give_up_call):
#define TRY_IT(func, ret, bad_ret_code, give_up_call, ...) \ if((ret) == (bad_ret_code)) { \ for(size_t i = 0; i <= TRY_IT_MAX_RETRIES; i++) { \ (ret) = (func)(__VA_ARGS__); \ if((ret) != (bad_ret_code)) \ break; \ if(i == TRY_IT_MAX_RETRIES) { \ give_up_call; \ } \ } \ }
关键修改点说明:
- 在宏的参数列表末尾加上
...,用来接收你要传给func的所有可变参数 - 把原来的
(func)()改成(func)(__VA_ARGS__),这样就把宏接收的可变参数原封不动传递给目标函数了
额外优化:处理无参数的情况
如果有时候你调用的func不需要参数,直接这么写可能会遇到编译器报错(因为多了个逗号),这时候可以用##__VA_ARGS__来自动消除多余的逗号,修改后的宏如下:
#define TRY_IT(func, ret, bad_ret_code, give_up_call, ...) \ if((ret) == (bad_ret_code)) { \ for(size_t i = 0; i <= TRY_IT_MAX_RETRIES; i++) { \ (ret) = (func)(##__VA_ARGS__); \ if((ret) != (bad_ret_code)) \ break; \ if(i == TRY_IT_MAX_RETRIES) { \ give_up_call; \ } \ } \ }
举个使用例子
比如你有个带参数的连接函数:
int connect_to_server(const char* server_addr, int port) { // 模拟连接逻辑,失败返回-1,成功返回0 return (rand() % 3 == 0) ? 0 : -1; }
用这个宏来重试连接的话,写法是这样的:
#define BAD_RET -1 #define TRY_IT_MAX_RETRIES 3 int ret = BAD_RET; TRY_IT(connect_to_server, ret, BAD_RET, fprintf(stderr, "连接失败,已达最大重试次数!\n"), "127.0.0.1", 8080);
这里最后两个参数"127.0.0.1"和8080就是直接传给connect_to_server的参数,完美适配你的需求~
内容来源于stack exchange
相关产品推荐
相关产品推荐

