简短版本:如何将变量参数函数中...
表示的内容传递给另一个函数,而不先将其解析为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
的内容相同。但是如何将...
参数传递给另一个函数?
答案 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。