formattable<T, charT>
default to char
?Section: 28.5.6.3 [format.formattable] Status: NAD Submitter: Jonathan Wakely Opened: 2022-10-28 Last modified: 2023-01-24
Priority: 2
View all other issues in [format.formattable].
View all issues with NAD status.
Discussion:
For many uses of <format>
there's no need to explicitly mention the output type as
char
. There are either typedefs for char
specializations (format_context
,
format_parse_context
, format_args
, etc.) or a default template argument
(formatter
, range_formatter
). But for the new formattable
concept you
always need to specify the character type:
static_assert( std::formattable<int> ); // ill-formed
static_assert( std::formattable<int, char> ); // OK
Should the concept have a default template argument for the second parameter, to make it easier to
check whether something is formattable
as char
?
[2022-11-01; Reflector poll]
Set priority to 2 after reflector poll. Two votes for NAD, the convenience makes it easier to misuse.
[2022-11-30; Reflector poll]
Set status to "Tentatively NAD" after ten votes in reflector poll.
[2022-11-30 LWG telecon. Status changed: Tentatively NAD → NAD.]
[2023-01-24 LEWG electronic poll; weak consensus to reject the propsed change.]
Proposed resolution:
This wording is relative to N4917.
Modify 28.5.1 [format.syn] as indicated:
[…] // 28.5.6 [format.formatter], formatter template<class T, class charT = char> struct formatter; // 28.5.6.3 [format.formattable], concept formattable template<class T, class charT = char> concept formattable = see below; […]
Modify 28.5.6.3 [format.formattable] as indicated:
[Drafting note: This repeats the default template argument already shown in the synopsis, which would not be valid in C++ code. That is consistent with our presentation style though, as this is not C++ code, it's a specification. See e.g.
indirect_strict_weak_order
andsubrange
.]
-1- Let
fmt-iter-for<charT>
be an unspecified type that modelsoutput_iterator<const charT&>
(24.3.4.10 [iterator.concept.output]).template<class T, class charT = char> concept formattable = semiregular<formatter<remove_cvref_t<T>, charT>> && requires(formatter<remove_cvref_t<T>, charT> f, const formatter<remove_cvref_t<T>, charT> cf, T t, basic_format_context<fmt-iter-for<charT>, charT> fc, basic_format_parse_context<charT> pc) { { f.parse(pc) } -> same_as<basic_format_parse_context<charT>::iterator>; { cf.format(t, fc) } -> same_as<fmt-iter-for<charT>>; };