如何将可变数量的参数转发给另一个函数?

时间:2013-05-08 18:44:30

标签: c++

在我的应用程序中,我有很多日志。我会在一个名为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包含一些奇怪的字符串 - 似乎没有传递变量参数。如何修复我的代码才有效?

3 个答案:

答案 0 :(得分:23)

C语言的典型表述是有两个函数,一个接受...,另一个接受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);
}

答案 1 :(得分:5)

简而言之,你不能。

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

答案 2 :(得分:0)

为了实现这一点,必须声明Logger::Error接受va_list作为参数,就像vfprintf一样,而不是像fprintf这样的...形式的变量参数。