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.

4500. constant_wrapper wording problems

Section: 21.3.5 [const.wrap.class] Status: New Submitter: Matthias Wippich Opened: 2026-01-07 Last modified: 2026-01-08

Priority: Not Prioritized

View other active issues in [const.wrap.class].

View all other issues in [const.wrap.class].

View all issues with New status.

Discussion:

During resolution of LWG 4383(i) prefix and postfix increment and decrement operators were changed to

template<constexpr-param T>
  constexpr auto operator++(this T) noexcept -> constant_wrapper<++Y>
    { return {}; }
template<constexpr-param T>
  constexpr auto operator++(this T, int) noexcept ->
    constant_wrapper<Y++> { return {}; }
template<constexpr-param T>
  constexpr auto operator--(this T) noexcept -> constant_wrapper<--Y>
    { return {}; }
template<constexpr-param T>
  constexpr auto operator--(this T, int) noexcept ->
    constant_wrapper<Y--> { return {}; }

However, we do not actually specify what Y is. Additionally, the assignment operator has been changed to

template<constexpr-param R>
  constexpr auto operator=(R) const noexcept
    -> constant_wrapper<X = R::value> { return {}; }

This is grammatically not valid C++. The assignment must be parenthesized.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 21.3.5 [const.wrap.class], class template constant_wrapper synopsis, as indicated:

    struct cw-operators { // exposition only// pseudo-mutators
      template<constexpr-param T>
        constexpr auto operator++(this T) noexcept
          -> constant_wrapper<++Y (++T::value)> { return {}; }
      template<constexpr-param T>
        constexpr auto operator++(this T, int) noexcept
          -> constant_wrapper<Y++ (T::value++)> { return {}; }
      template<constexpr-param T>
        constexpr auto operator--(this T) noexcept
          -> constant_wrapper<--Y (--T::value)> { return {}; }
      template<constexpr-param T>
        constexpr auto operator--(this T, int) noexcept
          -> constant_wrapper<Y-- (T::value--)> { return {}; }
      …
    };
    
    template<cw-fixed-value X, class>
    struct constant_wrapper : cw-operators {
      static constexpr const auto & value = X.data;
      using type = constant_wrapper;
      using value_type = decltype(X)::type;
    
      template<constexpr-param R>
        constexpr auto operator=(R) const noexcept
          -> constant_wrapper<(X = R::value)> { return {}; }
      constexpr operator decltype(auto)() const noexcept { return value; }
    };