Remove specialization template<size_t N> struct formatter<const charT[N], charT>
Mark de Wever

Created on 2022-11-27.00:00:00 last changed 2 months ago


Date: 2022-11-30.10:08:16

Proposed resolution:

This wording is relative to N4917.

  1. 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:

    1. (2.1) — The debug-enabled specializations […]

    2. (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>;
    3. (2.3) — […]

    4. (2.4) — […]

  2. 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.

Date: 2022-11-15.00:00:00

[ 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."

Date: 2022-11-27.00:00:00

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:

  1. Removing the specialization

    template<size_t N> struct formatter<const charT[N], charT>;
  2. Adding a specialization

    template<class charT, size_t N>
      constexpr range_format format_kind<const charT[N]> =

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.

Date User Action Args
2022-11-30 10:08:16adminsetmessages: + msg13129
2022-11-27 12:39:05adminsetmessages: + msg13118
2022-11-27 00:00:00admincreate