Title
Lvalue optional<NonMovable> does not satisify `view`, but is `viewable_range`
Status
new
Section
[optional] [ranges]
Submitter
Tomasz KamiƄski

Created on 2026-11-12.00:00:00 last changed 3 days ago

Messages

Date: 2026-11-12.00:00:00

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.

History
Date User Action Args
2026-11-12 00:00:00admincreate