C++ Logo


Advanced search

Re: [std-proposals] begin and end for std::optional

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Mon, 24 Oct 2022 21:03:52 +0200
pon., 24 paź 2022 o 20:01 Matt Heath via Std-Proposals
<std-proposals_at_[hidden]> napisał(a):
> 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.

Why do you in the first place whant use `std::join` there? Should not
be the correct abstraction to have some dedicated transformation that
filters all positions that are `true`
and then dereference them? And this will work with all pointers like
types, not only optional.
for(int n : opts | std::filter_and_dereference)
Make it very clear what happens there. Especially if someone tries to
use `std::optional<std::span<int>>` and confuse `x.value().begin()`
with `x.begin()`.

Received on 2022-10-24 19:04:05