在我的应用程序中,我有很多日志。我会在一个名为errorsLogger
的地方累积所有日志中的所有错误。我已经用这种方式实现了它:
static Logger errorsLogger;
....
void Logger::Error(std::string format, ...) {
va_list arglist;
va_start(arglist, format);
if (this != &errorsLogger) {
errorsLogger.Error(format, arglist); // how to forward parameters?
}
vfprintf(logFile, , format.c_str(), arglist);
fprintf(logFile, "\n");
fflush(logFile);
va_end( arglist );
}
但是这段代码没有按预期工作errorsLogger
包含一些奇怪的字符串 - 似乎没有传递变量参数。如何修复我的代码才有效?
答案 0 :(得分:23)
C语言的典型表述是有两个函数,一个接受...
,另一个接受va_list
(例如printf
对vprintf
)。在C ++中,使用重载很方便:
// public
void Logger::Error(const std::string& format, ...) {
va_list args;
va_start(args, format);
Error(format, args);
va_end(args);
}
// private
void Logger::Error(const std::string& format, va_list args) {
if (this != &errorsLogger)
errorsLogger.Error(format, args);
vfprintf(logFile, format.c_str(), args);
fprintf(logFile, "\n");
fflush(logFile);
}
使用C ++ 11,可以直接使用可变参数模板。您还可以将参数转发给C风格的可变参数函数。
template<class... Args>
void Logger::Error(const std::string& format, Args&&... args) {
if (this != &errorsLogger)
errorsLogger.Error(format, std::forward<Args>(args)...);
fprintf(logFile, format.c_str(), std::forward<Args>(args)...);
fprintf(logFile, "\n");
fflush(logFile);
}
答案 1 :(得分:5)
简而言之,你不能。
您所能做的就是编写一个等效的成员函数,该函数接受va_list
而不是变量参数,并将初始化的va_list
传递下去。
答案 2 :(得分:0)
为了实现这一点,必须声明Logger::Error
接受va_list
作为参数,就像vfprintf一样,而不是像fprintf这样的...
形式的变量参数。