Created on 2022-11-27.00:00:00 last changed 13 months ago
Proposed resolution:
This wording is relative to N4928.
Modify [format.formatter.spec] as indicated:
-2- Let charT be either char or wchar_t. Each specialization of formatter is either enabled or disabled, as described below. A debug-enabled specialization of formatter additionally provides a public, constexpr, non-static member function set_debug_format() which modifies the state of the formatter to be as if the type of the std-format-spec parsed by the last call to parse were ?. Each header that declares the template formatter provides the following enabled specializations:
(2.1) — The debug-enabled specializations […]
(2.2) — For each charT, the debug-enabled string type specializations
template<> struct formatter<charT*, charT>; template<> struct formatter<const charT*, charT>; template<size_t N> struct formatter<charT[N], charT>;template<size_t N> struct formatter<const charT[N], charT>;template<class traits, class Allocator> struct formatter<basic_string<charT, traits, Allocator>, charT>; template<class traits> struct formatter<basic_string_view<charT, traits>, charT>;(2.3) — […]
(2.4) — […]
Add a new paragraph to [diff.cpp20.utilities] as indicated:
Affected subclause: [format.formatter.spec]
Change: Removed the formatter specialization template<size_t N> struct formatter<const charT[N], charT>. Rationale: The specialization is inconsistent with the design of formatter, which is intended to be instantiated only with cv-unqualified object types. Effect on original feature: Valid C++ 2020 code that instantiated the removed specialization can become ill-formed.
[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP. ]
[ Issaquah 2023-02-08; LWG ]
Unanimous consent to move to Immediate.
[ 2023-02-07 Tim provides updated wording ]
[ 2022-11-30; Reflector poll ]
Set priority to 2 after reflector poll.
"Rationale is not really convincing why the first option is the right one."
"The point is not that we would need to add a format_kind specialization, it is that the specialization is inconsistent with the design of formatter, which is supposed to be instantiated only for cv-unqualified non-reference types."
This wording is relative to N4917.
Modify [format.formatter.spec] as indicated:
-2- Let charT be either char or wchar_t. Each specialization of formatter is either enabled or disabled, as described below. A debug-enabled specialization of formatter additionally provides a public, constexpr, non-static member function set_debug_format() which modifies the state of the formatter to be as if the type of the std-format-spec parsed by the last call to parse were ?. Each header that declares the template formatter provides the following enabled specializations:
(2.1) — The debug-enabled specializations […]
(2.2) — For each charT, the debug-enabled string type specializations
template<> struct formatter<charT*, charT>; template<> struct formatter<const charT*, charT>; template<size_t N> struct formatter<charT[N], charT>;template<size_t N> struct formatter<const charT[N], charT>;template<class traits, class Allocator> struct formatter<basic_string<charT, traits, Allocator>, charT>; template<class traits> struct formatter<basic_string_view<charT, traits>, charT>;(2.3) — […]
(2.4) — […]
Add a new paragraph to [diff.cpp20.utilities] as indicated:
Affected subclause: [format.formatter.spec]
Change: Remove the formatter specialization template<size_t N> struct formatter<const charT[N], charT>. Rationale: The formatter specialization was not used in the Standard library. Keeping the specialization well-formed required an additional format_kind specialization. Effect on original feature: Valid C++ 2020 code that instantiated the removed specialization is now ill-formed.
In the past I discussed with Victor and Charlie to remove
template<size_t N> struct formatter<const charT[N], charT>;
Charlie disliked that since MSVC STL already shipped it and Victor mentioned it was useful. Instead of proposing to remove the specialization in LWG 3701 ("Make formatter<remove_cvref_t<const charT[N]>, charT> requirement explicit") I proposed to keep it. It's unused but it doesn't hurt.
That was until P2585R0 "Improve default container formatting". This paper makes it no longer possible to instantiate this specialization. See here for an example and a possible work-around. The relevant wording is [format.syn]:template<class R> constexpr unspecified format_kind = unspecified; template<ranges::input_range R> requires same_as<R, remove_cvref_t<R>> constexpr range_format format_kind<R> = see below;
combined with [format.range.fmtkind] p1:
A program that instantiates the primary template of format_kind is ill-formed.
The issue is that const charT[N] does not satisfy the requirement same_as<R, remove_cvref_t<R>>. So it tries to instantiate the primary template, which is ill-formed.
I see two possible solutions:Removing the specialization
template<size_t N> struct formatter<const charT[N], charT>;
Adding a specialization
template<class charT, size_t N> constexpr range_format format_kind<const charT[N]> = range_format::disabled;
I discussed this issue privately and got no objection for solution 1, therefore I propose to take that route. Implementations can still implement solution 2 as an extension until they are ready to ship an API/ABI break.
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-22 15:47:43 | admin | set | status: wp -> c++23 |
2023-02-13 11:31:32 | admin | set | messages: + msg13390 |
2023-02-13 11:31:32 | admin | set | status: immediate -> wp |
2023-02-08 18:09:48 | admin | set | messages: + msg13293 |
2023-02-08 18:09:48 | admin | set | status: new -> immediate |
2023-02-07 23:05:30 | admin | set | messages: + msg13291 |
2022-11-30 10:08:16 | admin | set | messages: + msg13129 |
2022-11-27 12:39:05 | admin | set | messages: + msg13118 |
2022-11-27 00:00:00 | admin | create |