You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 12:43:03