Issue 3481: viewable_range mishandles lvalue move-only views (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 C++23 status.
3481. viewable_range mishandles lvalue move-only views
Section: 25.4.6 [range.refinements] Status: C++23 Submitter: Casey Carter Opened: 2020-08-29 Last modified: 2023-11-22
Priority: 2
View all other issues in [range.refinements].
View all issues with C++23 status.
Discussion:
The viewable_range concept (25.4.6 [range.refinements]) and the views:allrange adaptor (25.7.6 [range.all]) are duals: viewable_range is intended to admit exactly types T for which views::all(declval<T>()) is well-formed. (Recall that views::all(_meow_) is a prvalue whose type models view when it is well-formed.) Before the addition of move-only view types to the design, this relationship was in place (modulo an incredibly pathological case: a volatile value of a view type with volatile-qualified begin and end models viewable_range but is rejected by views::all unless it also has a volatile-qualified copy constructor and copy assignment operator). Adding move-only views to the design punches a bigger hole, however: viewable_range admits lvalues of move-only view types for which views::all is ill-formed because these lvalues cannot be decay-copied.
It behooves us to restore the correspondence between viewable_range and views::allso that instantiations of components constrained with viewable_range (which often appears indirectly as views::all_t<R> in deduction guides) continue to be well-formed when the constraints are satisfied.
[2020-09-06; Reflector prioritization]
Set priority to 2 during reflector discussions.
[2021-05-24; Reflector poll]
Set status to Tentatively Ready after five votes in favour during reflector poll.
[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4861.
- Modify 25.4.6 [range.refinements] as indicated:
-5- The
viewable_rangeconcept specifies the requirements of arangetype that can be converted to aviewsafely.template
concept viewable_range =
range &&(borrowed_range || view<remove_cvref_t>);
((view<remove_cvref_t> && constructible_from<remove_cvref_t, T>) ||
(!view<remove_cvref_t> && borrowed_range));