This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
std::format_kind for std::optional is not marked hostedSection: 16.3.3.7 [freestanding.item], 22.5.2 [optional.syn], 28.5.1 [format.syn] Status: New Submitter: Jiang An Opened: 2026-05-29 Last modified: 2026-05-29
Priority: Not Prioritized
View all other issues in [freestanding.item].
View all issues with New status.
Discussion:
Currently, <optional> is a mostly freestanding header and provides a partial specialization of
std::format_kind which isn't mark // hosted in the synopsis (22.5.2 [optional.syn]). The current
rules in 16.3.3.7 [freestanding.item] p4 seemingly requires the partial specialization to be a
freestanding item, while nothing seems to requires the primary template (provided by <format>)
to be freestanding.
Proposed resolution:
This wording is relative to N5046.
[Drafting Note: Three options are prepared, depicted below by Option A, Option B, and Option C, respectively, where option C is mutually exclusive with option A and B.
Note that libstdc++ effectively implemented option A recently (in commit 23b9ac257cf508bc4fa479c82fcfc768c4abcd79).]
Option A: Just marking the partial specialization hosted
Modify 22.5.2 [optional.syn], header <optional> synopsis, as indicated:
[…] template<class T> constexpr bool ranges::enable_view<optional<T>> = true; template<class T> constexpr auto format_kind<optional<T>> = range_format::disabled; // hosted template<class T> constexpr bool ranges::enable_borrowed_range<optional<T&>> = true; […]
Option B: Adding a general rule that infers hosted-ness of specializations
Modify 16.3.3.7 [freestanding.item] as indicated:
-4- A declaration in a synopsis is a freestanding item if […]
-5- An entity or deduction guide is a freestanding item if its introducing declaration is not followed by a comment that includes hosted, and is: […] -6- A macro is a freestanding item if it is defined in a header synopsis and […] -?- A partial or full template specialization is not a freestanding item if its primary template is not a freestanding item.
Option C: Making range_format and format_kind freestanding
Modify Table 27 [tab:headers.cpp.fs] as indicated:
Table 27: C++ headers for freestanding implementations [tab:headers.cpp.fs] Subclause Header […]28.2 [charconv] Primitive numeric conversions <charconv>28.5 [format] Formatting <format>29.5 [rand] Random number generation <random>[…]
Modify 28.5.1 [format.syn], header <format> synopsis, as indicated:
[…] // 28.5.7 [format.range], formatting of ranges // 28.5.7.1 [format.range.fmtkind], variable template format_kind enum class range_format { disabled, map, set, sequence, string, debug_string }; template<class R> constexpr unspecified format_kind = unspecified; // freestanding template<ranges::input_range R> requires same_as<R, remove_cvref_t<R>> constexpr range_format format_kind<R> = see below; // freestanding […]