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.

4639. Lvalue optional<NonMovable> does not satisify view, but is viewable_range

Section: 22.5 [optional], 25 [ranges] Status: New Submitter: Tomasz KamiƄski Opened: 2026-11-12 Last modified: 2026-11-12

Priority: Not Prioritized

View all other issues in [optional].

View all issues with New status.

Discussion:

The C++26 P3168R2 marked all specializations of optional as the view (enable_view is true), however, for type M that is not movable, optional<M> does not satisfy the view concept.

Generally, overstating support in opt-in is accepted and unharmful, however the view concept decides whether a view adapter will store independent copy of the range, or a reference to it. In particular lvalue of before mentioned optional<M> satisfies viewable_range, and is wrapped in ref_view when adapted:

constexpr auto process_rvalue()
{
  std::pair<const std::string, int> p("test", 20);
  return std::optional(p) | std::views::keys; // ill-formed
}

constexpr auto process_lvalue()
{
  std::pair<const std::string, int> p("test", 20);
  std::optional opt(p);
  return opt | std::views::keys; // references opt and dangles
}

This behavior is not unique to optional, and can occur for a user defined "view" that fails to satisfy movable since C++20. The C++26 changes to optional make it more prominent.

Proposed resolution: