On Mon, 24 Oct 2022 at 19:01, Matt Heath via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
It is sometimes useful to treat an optional type as being a range with either one or zero elements. Rust has this feature, by making std::option implement IntoIterator. In C++ this would mean implementing overloads of std::begin and std::end taking std::optional<T> (and const std::optional) with :
     std::next(std::begin(op)) == std::end(op)
if o.has_value(), and
     std::begin(op) == std::end(op)
otherwise.

This would mostly be for piping a range of optionals into std::join to leave just the unwrapped values, as in:
std::vector<std::optional<int>> opts = {1, 2, std::nullopt, std::nullopt , 3 };
for(int n : opts | std::join )
     std::cout << n << " , ";
This has the benefit of avoiding the programmer having to call has_value() and value() explicitly, which I think is probably for the best in terms of safety.

I think you want P1255 "views::maybe" [and "views::nullable"].

You'd need to transform the opts, possibly:

for(int n : opts | std::views::transform(std::views::nullable) | std::join)

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1255r9.pdf