Библиотека FMT C++: позволяет пользователю задавать спецификаторы формата для пользовательского типа
У меня есть пользовательский тип, например
struct custom_type
{
double value;
};
Я хочу установить пользовательский форматтер FMT для этого типа. Я делаю следующее, и это работает:
namespace fmt
{
template <>
struct formatter<custom_type> {
template <typename ParseContext>
constexpr auto parse(ParseContext &ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const custom_type &v, FormatContext &ctx) {
return format_to(ctx.begin(), "{}", v.value);
}
};
}
Но проблема в том, что формат вывода задается кодом шаблона, с этим "{}"
выражение. И я хочу дать пользователю возможность самому определять формат строки.
Например:
custom_type v = 10.0;
std::cout << fmt::format("{}", v) << std::endl;//10
std::cout << fmt::format("{:+f}", v) << std::endl; //10.000000
Как я могу это сделать?
В настоящее время, когда я устанавливаю пользовательский формат строки, я получаю
what(): unknown format specifier
1 ответ
Решение
Наконец-то я это сделал. Я сохраню это здесь, на случай, если кому-то еще это понадобится.
template <>
struct formatter<custom_type> {
template <typename ParseContext>
constexpr auto parse(ParseContext &ctx) {
auto it = internal::null_terminating_iterator<char>(ctx);
std::string tmp;
while(*it && *it != '}')
{
tmp += *it;
++it;
}
m_format=tmp;
return internal::pointer_from(it);
}
template <typename FormatContext>
auto format(const custom_type &v, FormatContext &ctx) {
std::string final_string;
if(m_format.size()>0)
{
final_string="{:"+m_format+"}";
}
else
{
final_string="{}";
}
return format_to(ctx.begin(), final_string, v.value);
}
mutable std::string m_format;
};
Самое простое решение - унаследовать formatter<custom_type>
от formatter<double>
:
template <> struct fmt::formatter<custom_type> : formatter<double> {
auto format(custom_type c, format_context& ctx) {
return formatter<double>::format(c.value, ctx);
}
};