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

能否重载含__VA_ARGS__的日志宏?附重载实现尝试

宏重载实现多参数WriteLogs的可行性

需求与现有代码

我尝试重载WriteLogs宏以支持1个和2个参数的调用场景,现有实现代码如下:

template <typename... Args>
void WriteLog(const LogContext& logContext, const LogSettings& logSettings, std::string formatMsg, Args... args) {
    // ...
    printf("formatMsg", args...);
    // ...
}

#define WriteLog_1(message, ...) WriteLog(LogContext{__LINE__, __FILE__, __FUNCTION__}, LogSettings{false, 0}, message, ##__VA_ARGS__)
#define WriteLog_2(settings, message, ...) WriteLog(LogContext{__LINE__, __FILE__, __FUNCTION__}, settings, message, ##__VA_ARGS__)

#define EXPAND(x) x
#define GET_MACRO(_1, _2, NAME, ...) NAME
#define WriteLogs(...) EXPAND(GET_MACRO(__VA_ARGS__, WriteDebug2, WriteDebug1)(__VA_ARGS__))

期望实现的调用效果:

int main() {
   WriteLogs("hello %s, %d + %d = %d", "world", 2, 2, 5); // 期望调用WriteLog_1
   WriteLogs(LogSettings{true, 0}, "hello %s, %d + %d = %d", "world", 2, 2, 5); // 期望调用WriteLog_2
}

请问是否可以实现这样的宏重载?


分析与解答

可以实现,但现有代码存在两处关键错误,修正后即可正常工作:

  1. 宏名称拼写错误:GET_MACRO里的WriteDebug2、WriteDebug1应该对应定义好的WriteLog_2、WriteLog_1,名称必须完全一致,否则会找不到对应的宏。

  2. 参数匹配顺序问题:GET_MACRO的宏列表顺序需要匹配参数数量逻辑。当传入参数时,宏会从右往左匹配对应名称,当前需求是1个主参数时调用WriteLog_1、2个主参数时调用WriteLog_2,所以宏列表顺序应调整为WriteLog_2, WriteLog_1。

修正后的完整代码

template <typename... Args>
void WriteLog(const LogContext& logContext, const LogSettings& logSettings, std::string formatMsg, Args... args) {
    // 注意:原代码中printf的第一个参数是字符串字面量,需改为formatMsg的C风格字符串
    printf(formatMsg.c_str(), args...);
    // ...
}

#define WriteLog_1(message, ...) WriteLog(LogContext{__LINE__, __FILE__, __FUNCTION__}, LogSettings{false, 0}, message, ##__VA_ARGS__)
#define WriteLog_2(settings, message, ...) WriteLog(LogContext{__LINE__, __FILE__, __FUNCTION__}, settings, message, ##__VA_ARGS__)

#define EXPAND(x) x
#define GET_MACRO(_1, _2, NAME, ...) NAME
// 修正宏名称和匹配顺序
#define WriteLogs(...) EXPAND(GET_MACRO(__VA_ARGS__, WriteLog_2, WriteLog_1)(__VA_ARGS__))

额外提示

原WriteLog函数中的printf("formatMsg", args...)是错误写法,会固定输出字符串formatMsg,需改为printf(formatMsg.c_str(), args...)才能正确使用传入的格式串变量。


内容的提问来源于stack exchange,提问作者isrepeat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:55:28