Let's say I want to format a single object directly using std::formatter
, bypassing std::format
. How do I do that?
According to Formatter, I need to call .format(value, format_ctx)
, where format_ctx
is a std::format_context
or std::basic_format_context<...>
. But how do I construct this context?
The standard doesn't seem to provide a way to construct one. And looking at libstdc++ sources, the member variables of basic_format_context
are all private, there's no non-default constructor, and no way to set them without being a friend
.
Does this mean that std::formatter
is impossible to use manually by design?
Why am I doing this?
I want to format a value using the "debug format" ("{?:}"
) if it's supported, falling back to the regular "{}"
.
The way to check for support seems to be requires(std::formatter<T> f){f.set_debug_format();}
, and I figured that if I'm already interacting with the formatter directly, I might as well use only the formatter itself.
The use case you're describing, where you never actually call
std::(v)format(_to)
and just use the formatter directly, isn't supported. You should just callstd::format
with the format string that you want to use, i.e.,{}
or{:?}
.And even if you could bypass
std::format
, you would just be creating work for yourself. You'd have to callstd::formatter<T>::parse
andstd::formatter<T>:format
manually (since the former sets up state that is used by the latter). And you'd have to manually set up the contents of thestd::basic_format_parse_context
andstd::basic_format_context
objects, assuming that they supported that in the first place.On the other hand, a formatter can invoke another formatter, by passing down the
std::basic_format_parse_context
and later thestd::basic_format_context
that were passed to it by the library. That's basically how you'd implement a range formatter (if it weren't for the fact that the standard already provides one).