Проблема с форматированием пользовательских типов в библиотеке fmt
Я столкнулся с проблемой форматирования пользовательского типа и закончил этим простым примером на основе документации fmt.
struct point_double {
double x, y;
operator const char*() const {
return nullptr;
}
};
namespace fmt {
template <>
struct formatter<point_double> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const point_double& p, FormatContext& ctx) {
return format_to(ctx.out(), "({:.1f}, {:.1f})", p.x, p.y);
}
};
} // namespace fmt
void foo() {
point_double p = {1, 2};
fmt::print("{}\n", p);
}
призвание foo
произойдет сбой, потому что пользовательский форматер не используется. Вместо fmt::print
будет использовать форматировщик строки по умолчанию и аварийно завершит работу при возврате оператора nullptr
, Есть ли способ обойти эту проблему? Я использую FMT 5.3.0
1 ответ
Вы не можете иметь неявное преобразование в const char*
и formatter
специализация (теперь {fmt} даст вам ошибку во время компиляции), потому что const char*
уже форматируется. Если у вас есть контроль над point_double
простое решение - сделать оператор преобразования явным, что в целом является хорошей идеей. В противном случае вы можете обернуть point_double
в другом типе и обеспечить formatter
специализация для этого.