Reputation: 651
I faced a problem for formatting a user-defined type and ended up with this simple example based on fmt documentation.
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);
}
Calling foo
will crash because the user-defined formatter is not used. Instead fmt::print
will use the default string formatter and crash as the operator returns nullptr
.
Is there a way to go around this issue? I'm using fmt 5.3.0
Upvotes: 2
Views: 1468
Reputation: 55595
You cannot have both an implicit conversion to const char*
and a formatter
specialization ({fmt} will now give you a compile-time error), because const char*
is already formattable. If you have control over point_double
, an easy solution is to make the conversion operator explicit which is a good idea in general. Otherwise you can wrap point_double
in another type and provide a formatter
specialization for that.
Upvotes: 1