Issue 4398: enable_nonlocking_formatter_optimization should be disabled for container adaptors (original) (raw)


This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

4398. enable_nonlocking_formatter_optimization should be disabled for container adaptors

Section: 23.6.2 [queue.syn], 23.6.5 [stack.syn] Status: WP Submitter: Tomasz Kamiński Opened: 2025-10-02 Last modified: 2025-11-11

Priority: 2

View all issues with WP status.

Discussion:

As the standard currently defines formatters for queue, prioriy_queue, and stack enable_nonlocking_formatter_optimization is specialized to true for these adaptors per 28.5.6.4 [format.formatter.spec] p3:

Unless specified otherwise, for each type T for which a formatter specialization is provided by the library, each of the headers provides the following specialization:

template<> inline constexpr bool enable_nonlocking_formatter_optimization = true;

However, formatting an adaptor requires formatting of the underlying range in terms of ranges::ref_view, and we disable the nonlocking_optimizations for all ranges, including ranges::ref_view.

This problem does not occur for the flat_set, flat_map adaptors, which are also ranges, but unlike stack etc. they do not have a specialized formatter. They use the formatter specialization for ranges and we already disable the optimization for that formatter.

The proposed wording has recently been implemented in gcc's libstdc++.

[2025-10-14; Reflector poll]

Set priority to 2 after reflector poll.

This is a duplicate of LWG 4146(i), with a different proposed resolution.

[2025-10-17; Reflector poll]

Set status to Tentatively Ready after five votes in favour during reflector poll.

[Kona 2025-11-08; Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N5014.

  1. Modify 23.6.2 [queue.syn], header <queue> synopsis, as indicated:

    […]
    // 23.6.13 [container.adaptors.format], formatter specialization for queue
    template<class charT, class T, formattable Container>
    struct formatter<queue<T, Container>, charT>;

    template<class T, class Container>
    constexpr bool enable_nonlocking_formatter_optimization<queue<T, Container>> = false;

    // 23.6.4 [priority.queue], class template priorityqueue
    template<class T, class Container = vector,
    class Compare = less>

class priority_queue;
[…]
// 23.6.13 [container.adaptors.format], formatter specialization for priorityqueue
template<class charT, class T, formattable Container, class Compare>
struct formatter<priority_queue<T, Container, Compare>, charT>;

template<class T, class Container, class Compare>
constexpr bool enable_nonlocking_formatter_optimization<priority_queue<T, Container, Compare>> = false;
[…] 2. Modify 23.6.5 [stack.syn], header <stack> synopsis, as indicated:
[…]

// 23.6.13 [container.adaptors.format], formatter specialization for stack
template<class charT, class T, formattable Container>
struct formatter<stack<T, Container>, charT>;

template<class T, class Container>
constexpr bool enable_nonlocking_formatter_optimization<stack<T, Container>> = false;

[…]