Revised 2026-09-14 at 09:14:27 UTC

Tentative Issues


4458(i). indirect<T> should be convertible to T&

Section: 20.5.1.6 [indirect.obs] Status: Tentatively NAD Submitter: Zhihao Yuan Opened: 2025-11-05 Last modified: 2026-09-10

Priority: Not Prioritized

Discussion:

Addresses US 77-140

In addition to serving as a better unique_ptr<T> in Pimpl, indirect<T> can also appear as a drop-in replacement for T when T may conditionally be an incomplete type. In which case, if indirect<T> is convertible to T&, certain tasks can be done without meta-programming (e.g., returning the object of type T or indirect<T> from a function with a return type T&).

[2026-08-27; Reflector poll. Status → Tentatively NAD.]

This is a design change; LEWG rejected the comment for C++26. LEWG can revisit for C++29 if a paper is submitted.

Proposed resolution:

This wording is relative to N5014.

  1. Modify 20.5.1.2 [indirect.syn], as indicated:

    namespace std {
      template<class T, class Allocator = allocator<T>>
      class indirect {
      public:
        […]
        // 20.5.1.6 [indirect.obs], observers
        constexpr operator const T& () const & noexcept;
        constexpr operator T& () & noexcept;
        constexpr operator const T&& () const && noexcept;
        constexpr operator T&& () && noexcept;
        constexpr const T& operator*() const & noexcept;
        constexpr T& operator*() & noexcept;
        constexpr const T&& operator*() const && noexcept;
        constexpr T&& operator*() && noexcept;
        constexpr const_pointer operator->() const noexcept;
        constexpr pointer operator->() noexcept;
        […]
    
  2. Modify 20.5.1.6 [indirect.obs], as indicated:

    constexpr operator const T& () const & noexcept;
    constexpr operator T& () & noexcept;
    constexpr const T& operator*() const & noexcept;
    constexpr T& operator*() & noexcept;
    

    -1- Preconditions: *this is not valueless.

    -2- Returns: *p.

    constexpr operator const T&& () const && noexcept;
    constexpr operator T&& () && noexcept;
    constexpr const T&& operator*() const && noexcept;
    constexpr T&& operator*() && noexcept;
    

    -3- Preconditions: *this is not valueless.

    -4- Returns: std::move(*p).


4592(i). Preconditions of some virtual functions std::codecvt on character ranges are in a possibly unintended form

Section: 28.3.4.2.5.3 [locale.codecvt.virtuals] Status: Tentatively Ready Submitter: Jiang An Opened: 2026-06-01 Last modified: 2026-09-10

Priority: Not Prioritized

View other active issues in [locale.codecvt.virtuals].

View all other issues in [locale.codecvt.virtuals].

View all issues with Tentatively Ready status.

Discussion:

Currently, some preconditions in 28.3.4.2.5.3 [locale.codecvt.virtuals] require that "first <= last is well-defined and true", where first and last are pointer parameters that are intended to denote a range. These preconditions seem specified too relaxedly, and make some necessary preconditions implicitly specified in Effects. Per 7.6.9 [expr.rel], comparing pointers that are not associated with the same storage instance still has well-defined behavior although the result is unspecified. And even if the result is specified to be true, it's possible for first and last to point to elements of different array subobjects in the same complete object, which renders last not reachable from first.

[2026-08-27; Reflector poll.]

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

This change has no practical impact, because this was always the real precondition anyway.

Proposed resolution:

This wording is relative to N5046.

  1. Modify 28.3.4.2.5.3 [locale.codecvt.virtuals] as indicated:

    result do_out(
      stateT& state,
      const internT* from, const internT* from_end, const internT*& from_next,
      externT* to, externT* to_end, externT*& to_next) const;
      
    result do_in(
      stateT& state,
      const externT* from, const externT* from_end, const externT*& from_next,
      internT* to, internT* to_end, internT*& to_next) const;
    

    -1- Preconditions: (from <= from_end && to <= to_end) is well-defined and true[from, from_end) and [to, to_end) are both valid ranges; state is initialized, if at the beginning of a sequence, or else is equal to the result of converting the preceding characters in the sequence.

    […]

    result do_unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
    

    -7- Preconditions: (to <= to_end) is well-defined and true[to, to_end) is a valid range; state is initialized, if at the beginning of a sequence, or else is equal to the result of converting the preceding characters in the sequence.

    […]

    […]
    int do_length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
    

    -12- Preconditions: (from <= from_end) is well-defined and true[from, from_end) is a valid range; state is initialized, if at the beginning of a sequence, or else is equal to the result of converting the preceding characters in the sequence.

    […]


4593(i). The first template argument of std::saturating_cast must be specifiable

Section: 26.10.17.2 [numeric.sat.cast] Status: Tentatively Ready Submitter: Jiang An Opened: 2026-06-02 Last modified: 2026-09-10

Priority: Not Prioritized

View all issues with Tentatively Ready status.

Discussion:

Currently, 26.2 [algorithms.requirements]/15 allows implementations to reject explicitly specifying template arguments for algorithms. Unfortunately, std::saturating_cast is also an algorithm as it is specifying in the "Algorithms library" chapter, and its first template argument must be explicitly specified. Without being "explicitly stated otherwise", std::saturating_cast is effectively unusable.

[2026-08-27; Reflector poll.]

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

Proposed resolution:

This wording is relative to N5046.

  1. Modify 26.10.17.2 [numeric.sat.cast] as indicated:

    template<class R, class T>
      constexpr R saturating_cast(T x) noexcept;
    

    -1- Constraints: R and T are signed or unsigned integer types (6.9.3 [basic.fundamental]).

    -2- Returns: If x is representable as a value of type R, x; otherwise, either the largest or smallest representable value of type R, whichever is closer to the value of x.

    -?- Remarks: An invocation may explicitly specify an argument for the template parameter R.


4598(i). §[res.on.exception.handling] should cover exceptions specified outside a Throws: paragraph

Section: 16.4.6.14 [res.on.exception.handling] Status: Tentatively Ready Submitter: Louis Dionne Opened: 2026-06-18 Last modified: 2026-09-10

Priority: Not Prioritized

View other active issues in [res.on.exception.handling].

View all other issues in [res.on.exception.handling].

View all issues with Tentatively Ready status.

Discussion:

16.4.6.14 [res.on.exception.handling] p1 permits a standard library function to throw a type derived from the one it is specified to throw:

Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph, or of a type derived from a type named in the Throws: paragraph that would be caught by a handler for the base type.

This is worded purely in terms of the function's Throws: paragraph. However, many functions specify the exception they throw outside of a Throws: paragraph. For example, std::get on a variant specifies it in an Effects: clause, 22.6.5 [variant.get] p7:

Effects: If v.index() is I, returns a reference to the object stored in the variant. Otherwise, throws an exception of type bad_variant_access.

Read literally, 16.4.6.14 [res.on.exception.handling] p1 does not grant implementations the ability to throw a derived type, because the exception is described in an Effects: paragraph. I believe this is unintended: the permission should apply whenever the standard specifies that a function throws an exception of a given type, regardless of which clause says so.

[2026-09-09; Reflector poll.]

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

Proposed resolution:

This wording is relative to N5046.

  1. Modify 16.4.6.14 [res.on.exception.handling] as indicated:

    -1- Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraphthat the function is specified to throw (whether in a Throws: paragraph or elsewhere in its specification), or of a type derived from a type named in the Throws: paragraphsuch a type that would be caught by a handler (14.4 [except.handle]) for the base type.


4605(i). Feature test macro for error_code formatting

Section: 17.3.2 [version.syn] Status: Tentatively Ready Submitter: Jonathan Wakely Opened: 2026-07-17 Last modified: 2026-09-10

Priority: Not Prioritized

View other active issues in [version.syn].

View all other issues in [version.syn].

View all issues with Tentatively Ready status.

Discussion:

P3395R6 added a std::formatter specialization for error_code, but without a feature test macro. During the review of the pull request to apply the paper to the working draft there were requests for a feature test macro.

[2026-08-27; Reflector poll.]

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

Proposed resolution:

This wording is relative to N5050.

  1. Modify 17.3.2 [version.syn] as indicated:

    #define __cpp_lib_format             202603L // also in <format>
    #define __cpp_lib_format_error_code  202606L // also in <system_error>
    #define __cpp_lib_format_path        202506L // also in <filesystem>