我有这个Log函数调用我的logger(spdlog)方法:
template<typename... Args>
void Log(const char* fmt,
const Args&... args)
{
g_FileLogger->log(fmt, args...);
}
我想将我的记录器(spdlog,由g_FileLoggre表示)更改为另一个记录器。不幸的是,“fmt”字符串包含“{}”,它们是变量“args”的占位符。我想用正确的格式说明符(%s,%zu,%d等......)更改那些“{}”和其他记录器一样,我必须指定正确的格式说明符。
您能否给我一个快速安全的解决方案来生成一个字符串,用正确的变量格式说明符替换“{}”。
否则,spdlog是一个很好的日志API,但由于它的API已被破坏,我们决定选择另一个记录器,例如在Centos中API已经过时了,而在Gentoo中它更新,代码将无法编译。
答案 0 :(得分:1)
创建format_converter
功能
template<typename... Args>
std::string format_converter(const char* fmt,
const Args&... args)
{...}
解析fmt字符串并根据参数进行转换。
然后修改你的功能:
template<typename... Args>
void Log(const char* fmt,
const Args&... args)
{
auto new_fmt = format_converter(fmt, args...);
new_logger->log( new_fmt, args... );
}
编辑:
在format_converter
中,模板函数可用于将参数类型转换为字符串。例如:
template< typename T >
const char* type_string( const T ); // primary template
const char* type_string( const char* ) // overload for c-string
{
return "%s";
}
template<>
const char* type_string< double >( const double ) // partial specialization for double
{
return "%d";
}
template<>
const char* type_string< int >( const int ) // partial specialization for int
{
return "%i";
}
// .....
答案 1 :(得分:1)
创建convert_format
函数,将{..}
替换为您指定的内容。创建一个包含要替换的数据的std::map<std::string, std::string>
对象。
#include <string>
#include <map>
std::string convert_format(const std::string& format, std::map<std::string, std::string> format_map) {
string ret;
for (int x = 0; x != format.size(); ++x) {
if (format[x] == '{') {
std::string key;
++x;
for (; x != format.size(); ++x) {
if (format[x] == '}') {
auto itr = format_map.find(key);
if (itr != format_map.end()) {
ret += (*itr).second;
}
break;
} else {
key.push_back(format[x]);
}
}
} else {
ret.push_back(format[x]);
}
}
return ret;
}
现在将Log
函数修改为:
template<typename... Args>
void Log(const char* fmt,
const Args&... args)
{
// map that will contain the data.
std::map<std::string, std::string> format_map;
// IF you have an args named as number and a string
// replaces {number} with %d
format_map["number"] = "%d";
// for replacing '{string}' with %s
format_map["string"] = "%s"; // ... and so on
auto new_fmt = convert_format(std::string(fmt), format_map);
new_logger->log( new_fmt, args... );
}
编辑:我认为您需要一个将变量的名称和值传递给函数Log
的宏。