[英]Passing variadic parameters from a function to another?
由于我不想在这里重复代码,我试图找出一种方法将这些记录器功能(例如调试、警告、信息等)中的每一个的公共部分移动到另一个 function 中。 我自己尝试过一种天真的方法,但似乎不能正常工作。 我想我需要直接传递一个va_list
但这样做我不知道首先创建一个单独的 function 是否值得。 关于如何实现这一目标的任何想法/建议?
原来的
void ConsoleLogger::debug(const char *fmt...)
{
if (static_cast<uint8_t>(LogLevel::DEBUG) <= static_cast<uint8_t>(configuration.priority))
{
va_list args;
char log_text[LOG_MAX_LENGTH];
va_start(args, fmt);
vsnprintf(log_text, LOG_MAX_LENGTH, fmt, args);
va_end(args);
std::cout << get_time_as_string() + " [DEBUG] " + log_text + "\n";
std::cout.flush();
}
}
我的镜头没有按预期工作,因为 log_text 填充了错误/随机字符,而在原始中它打印了正确的字符串。
const std::string Logger::get_log_text(const char *fmt...) const
{
va_list args;
char log_text[LOG_MAX_LENGTH];
va_start(args, fmt);
vsnprintf(log_text, LOG_MAX_LENGTH, fmt, args);
va_end(args);
return std::string(log_text);
}
void ConsoleLogger::debug(const char *fmt...)
{
if (static_cast<uint8_t>(LogLevel::DEBUG) <= static_cast<uint8_t>(configuration.priority))
{
std::string log_text = get_log_text(fmt);
std::cout << get_time_as_string() + " [DEBUG] " + log_text + "\n";
std::cout.flush();
}
}
好吧,首先这个答案并没有从字面上回答这个问题,因为我对C可变参数函数不是特别熟悉,但它可以解决您的实际问题,并且在C++中也更推荐。
template <class ...args_t>
const std::string get_log_text(const char *fmt, args_t &&...args)
{
char log_text[LOG_MAX_LENGTH];
sprintf(log_text, fmt, std::forward<args_t>(args)...);
return std::string(log_text);
}
template <class ...args_t>
void debug(const char *fmt, args_t &&...args)
{
if (static_cast<uint8_t>(LogLevel::DEBUG) <= static_cast<uint8_t>(configuration.priority))
{
std::string log_text = get_log_text(fmt, std::forward<args_t>(args)...);
std::cout << get_time_as_string() + " [DEBUG] " + log_text + "\n";
std::cout.flush();
}
}
因此,由于使用可变参数模板看起来是解决这个问题的最佳现代解决方案,我最终得到了以下解决方案,其中每个日志 function(调试、警告等)不再需要专门化。 自从我使用c++17
进行编译以来,我从这个建议中获得了使用折叠表达式的灵感。
template <typename... T> void debug(const T &...args)
{
if (static_cast<uint8_t>(LogLevel::DEBUG) <= static_cast<uint8_t>(configuration.priority))
{
std::string final_text = "[DEBUG] " + get_log_text(args...);
log(final_text); // this is specialized in every Logger derived class depending on the type
}
}
template <typename... T> const std::string get_log_text(T &...args) const
{
std::ostringstream log_text;
((log_text << std::forward<T>(args)), ...);
return log_text.str();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.