16

在我的应用程序中,我有很多日志。我确实将所有日志中的所有错误累积在一个名为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其中包含一些奇怪的字符串-似乎未传递变量参数。如何修复我的代码有效?

4

3 回答 3

26

在 C 中的典型表述是有两个函数,一个接受...,一个接受 a va_list(例如,printfvprintf)。在 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);
}
于 2013-05-08T18:58:10.360 回答
5

简而言之,你不能。

您所能做的就是编写一个等效的成员函数,该函数接受 ava_list而不是变量参数,并将初始化的值va_list向下传递。

于 2013-05-08T18:48:10.200 回答
0

为此,Logger::Error必须声明接受 ava_list作为参数,很像 vfprintf,而不是 ...像 fprintf 形式的变量参数。

于 2013-05-08T18:49:49.093 回答