std::format of user-defined types?
std::format
doesn't support operator<<
, you need to provide a formatter
specialization for your type (Point
) instead. The easiest way to do it is by reusing one of existing formatters, e.g. std::formatter<std::string>
:
template <>
struct std::formatter<Point> : std::formatter<std::string> {
auto format(Point p, format_context& ctx) {
return formatter<string>::format(
std::format("[{}, {}]", p.x, p.y), ctx);
}
};
This will give you all format specifications supported by std::string
out of the box. Here is an example of formatting Point
with center alignment padded with '~' to 10 characters:
auto s = std::format("{:~^10}", Point{1, 2});
// s == "~~[1, 2]~~"
which is nontrivial to achieve with iostreams.
You have to specialize std::formatter
for your type.
namespace std
{
template<class CharT>
struct formatter<Point, CharT>
{
template <typename FormatParseContext>
auto parse(FormatParseContext& pc)
{
// parse formatter args like padding, precision if you support it
return pc.end(); // returns the iterator to the last parsed character in the format string, in this case we just swallow everything
}
template<typename FormatContext>
auto format(Point p, FormatContext& fc)
{
return std::format_to(fc.out(), "[{}, {}]", p.x, p.y);
}
};
}
I don't think the ostream operator will work but I have no sources to support this claim.