das*_*ang 9 c++ overloading variadic
我有这个日志系统,我正在寻找一些字符串操作的快捷方式.
日志系统通过功能宏使用,然后转发到单个函数调用.例如#define Warning(...) LogMessage(eWarning, __VA_ARGS__);.
然后LogMessage snprintf进入一个新的缓冲区,然后将该消息提供给碰巧安装的任何日志目标; printf,OutputDebugString等
不幸的是,我遇到了一个问题,即我们所拥有的缓冲区不够大,因此输出会被截断.我还意识到,如果输出消息中包含百分比符号,则此方法将失败,因为snprintf将尝试处理va_args.最后,因为我们的大多数日志消息都不使用va_args,所以复制字符串只是为了将它呈现给记录器似乎很愚蠢.
那么 - 鉴于我的函数原型,我是否应该能够根据省略号的存在进行重载?换句话说,我是否可以假设我可以做以下事情:
LogMessage(LogLevel, const char* message, ...);
LogMessage(LogLevel, const char* message);
Run Code Online (Sandbox Code Playgroud)
我的谷歌尝试没有产生任何特别有用的东西(只是告诉我椭圆将匹配,如果没有别的,根据我的要求,没有任何匹配),我的初始实施只是给了我一个模糊的函数调用错误.
有了这个错误,我应该接受我不能这样做,但我想知道它是否只是我正在使用的编译器,或者我是否做错了.我可以达到类似的效果
// edited version of what I really have to remove our local APIs,
// please excuse minor errors
const char* message = NULL;
char buffer[512];
va_list args;
va_start(args, format);
if(strcmp(format, "%s") == 0) {
message = va_arg(args, const char*);
}
else if (strchr(format, '%') == NULL) {
message = format;
}
else {
vsnprintf(buffer, 512, format, args);
message = buffer;
}
va_end(args);
Run Code Online (Sandbox Code Playgroud)
......但这在典型的情况下似乎是浪费的,这可以通过传递的参数数量简单地知道.例如,如果省略号与任何东西不匹配,请选择其他函数?如果这不起作用,是否有另一种我可以尝试的方法,不需要用户决定使用宏名称将调用哪个函数?老实说,一旦我意识到如果有人随意地Error("Buffer not 100% full");在他们的日志消息中说并且因此得到"缓冲区不是1007.732873e10ull" ,那么"废物" 就不那么多了.
编辑:虽然我的例子已被"不要那样做"回答,但问题本身可以回答吗?
我受到这个问题最初答案的启发,但提出了一些改进。
static void LogMessage(LogLevel level, const char* message);
template <typename T>
static void LogMessage(LogLevel level, const char* format, T t, ...)
{
LogMessageVA(level, format, (va_list)&t);
}
static void LogMessageVA(LogLevel level, const char* format, va_list argptr);
Run Code Online (Sandbox Code Playgroud)
这无需“假设”第二个参数是 const char* 即可工作。