如何将变量参数参数传递给另一个函数?

时间:2012-12-06 17:10:11

标签: c++ c variadic-functions

简短版本:如何将变量参数函数中...表示的内容传递给另一个函数,而不先将其解析为va_list

长版:

以下是我的一类中的两个功能。我想提请你注意每个功能的前四行是相同的。我在这个类中有六个其他函数,前四行相同。

void cyclOps::Logger::warn(char* szFile, char* szFunction, int iLine, char* szFormat, ...) {
    va_list vaArguments;
    va_start(vaArguments, szFormat);
    char szOutput[10000];
    _vsnprintf_s(szOutput, CYCLOPSSIZEOF(szOutput), _TRUNCATE, szFormat, vaArguments);
    this->log("WARNING: %s [%s - %s(%d)]", szOutput, szFile, szFunction, iLine);
}

void cyclOps::Logger::info(char* szFormat, ...) {
    va_list vaArguments;
    va_start(vaArguments, szFormat);
    char szOutput[10000];
    _vsnprintf_s(szOutput, CYCLOPSSIZEOF(szOutput), _TRUNCATE, szFormat, vaArguments);
    this->log("INFO: %s", szOutput);
}

我想将这四条完全相同的行放在一个名为summarizeVariableArguments()的函数中,并将其命名为...

void cyclOps::Logger::info(char* szFormat, ...) {
      std::string strOutput = this->summarizeVariableArguments(/* TBD */);
    this->log("INFO: %s", strOutput.c_str());
}

... strOutput的内容与前两个函数中szOutput的内容相同。但是如何将...参数传递给另一个函数?

3 个答案:

答案 0 :(得分:4)

你不能这样做(或者在编译时,使用可怕的C ++ 2011可变参数模板技巧)。

如果要在运行时调用可变参数函数,可能需要使用libffi

详细信息是操作系统,编译器,处理器和ABI特定的。 (但libffi正试图抽象它们。)

答案 1 :(得分:4)

That's what perfect forwarding is all about +可变参数模板。

template<typename ...Args>
void cyclOps::Logger::info(char* szFormat, Args &&...args) {
    std::string strOutput = this->summarizeVariableArguments(std::forward<Args>(args)...);
    this->log("INFO: %s", strOutput.c_str());
}

答案 2 :(得分:2)

你创建另一个接受va_list的函数来完成这样的工作:

void cyclOps::Logger::vLog(const char* format, va_list args)
{
    std::string logMessage = vFormat<10000>(format, args);
    // Do what you want with logMessage
}

template <size_t BufferSize>
std::string cyclOps::Logger::vFormat(const char* format, va_list args)
{
    char buffer[BufferSize];
    vsprintf(buffer, format, args);
    return std::string(buffer);
}

我在MSVC和GCC上为我的项目测试了这个。我只能说它对我有用。

这是一个working example。这个解决方案适用于C ++ 03,我相信它应该适用于C ++ 11。