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

### 3811. `views::as_const` on `ref_view<T>` should return `ref_view<const T>`

Section: 26.7.21.1 [range.as.const.overview] Status: Ready Submitter: Tomasz Kamiński Opened: 2022-11-03 Last modified: 2022-11-10

Priority: Not Prioritized

View all issues with Ready status.

Discussion:

For `v` being a non-const lvalue of type `std::vector<int>`, `views::as_const(v)` produces `ref_view<std::vector<int> const>`. However, when `v` is converted to `ref_view` by using `views::all`, `views::as_const(views::all(v))` produces `as_const_view<ref_view<std::vector<int>>>`.

Invoking `views::as_const` on `ref_view<T>` should produce `ref_view<const T>` when `const T` models a constant range. This will reduce the number of instantiations, and make a behavior of `views::as_const` consistent on references and `ref_view` to containers.

[Kona 2022-11-08; Move to Ready]

Proposed resolution:

This wording is relative to N4917.

1. Modify 26.7.21.1 [range.as.const.overview] as indicated:

   > [Drafting note: If we have `ref_view<V>`, when `V` is constant propagating view (`single_view`, `owning_view`), we still can (and should) produce `ref_view<V const>`. This wording achieves that.]

   > -2- The name `views::as_const` denotes a range adaptor object (26.7.2 [range.adaptor.object]). Let `E` be an expression, let `T` be `decltype((E))`, and let `U` be `remove_cvref_t<T>`. The expression `views::as_const(E)` is expression-equivalent to:

   > 1. (2.1) — If `views::all_t<T>` models `constant_range`, then `views::all(E)`.

   > 2. (2.2) — Otherwise, if `U` denotes `span<X, Extent>` for some type `X` and some extent `Extent`, then `span<const X, Extent>(E)`.

   > 3. (2.?) — Otherwise, if `U` denotes `ref_view<X>` for some type `X` and `const X` models `constant_range`, then `ref_view(static_cast<const X&>(E.base()))`.

   > 4. (2.3) — Otherwise, if `E` is an lvalue, `const U` models `constant_range`, and `U` does not model `view`, then `ref_view(static_cast<const U&>(E))`.

   > 5. (2.4) — Otherwise, `as_const_view(E)`.