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::formatwith 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>::parseandstd::formatter<T>:formatmanually (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_contextandstd::basic_format_contextobjects, 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_contextand later thestd::basic_format_contextthat 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).