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.

4221. Cannot format const-iterable only ranges

Section: 28.5.7 [format.range] Status: New Submitter: Hewill Kang Opened: 2025-03-06 Last modified: 2025-10-21

Priority: 2

View all issues with New status.

Discussion:

The standard does not explicitly prohibit ranges that are only const-iterable, i.e. a range with const begin() and deleted or invalid non-const begin().

Unfortunately, those ranges cannot be formatted because the R in formatter<R> is always without the const-qualifier, which makes it never satisfy the range concept (demo):

#include <print>
#include <ranges>

struct R {
  int* begin() = delete;
  int* end() = delete;
  const int* begin() const;
  const int* end() const;
};

int main() {
  const R r;
  static_assert(std::ranges::contiguous_range<decltype(r)>);

  for (auto&& elem : r)
    std::print("{} ", elem); // ok

  std::ranges::for_each(
    r, [](auto&& elem) { std::print("{} ", elem); }
  );                         // ok

  std::print("{}", r);       // not ok
}

Although such type might be relatively rare, it does reflect an inconsistency in the general usage of formatting ranges, which do not support all valid ranges.

[2025-10-21; Reflector poll.]

Set priority to 2 after reflector poll.

The majority voted NAD, because the range shown in the issue is nonsensical. But enough people voted P2 that we should not close it without more discussion.

Proposed resolution: