C++ Logo

std-proposals

Advanced search

Re: [std-proposals] contiguous_iterator is too restrictive in C++26 std::optional<T&>

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Fri, 16 Aug 2024 18:00:25 +0100
Hi,

I think it's possible to implement a contiguous iterator in the shape of struct { T* ptr; bool is_end; }; and still satisfy the semantic constraints.

The only operation that would require a complete type is `to_address` , which you don't use in your examples.

It's still not necessarily a good idea though.

Cheers,
Lénárd



On 16 August 2024 13:00:12 BST, Piotr Nycz via Std-Proposals <std-proposals_at_[hidden]> wrote:
>Hi,
>
>I have a small request(bug fix? improvement) to existing (probably accepted
>already) proposals to C++26 about std::optional class.
>
>I am pretty sure (I tested it) that contiguous_iterator as specified in
>this paper Give std::optional Range Support
><https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3168r2.html> is
>too restrictive as for next proposal - std::optional<T&>
><https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2988r3.pdf>
>In my opinion it should be just input_iterator.
>
>The main reason is that for input_iterator I wouldn't need to have T
>defined - it can still be forward declared - thus compilation time will not
>have to increase - nor I have to add any extra includes when changing from:
>
>struct Some;
>void func(Some&);
>std::optional<Some&> a = get();
>
>if (a) func(*a);
>
>to:
>
>...
>for (auto& v: a) func(v);
>
>The other reasons - who would care if the iterator type to 0-or-1 range is
>contiguous or not, then no need to complicate...
>
>I have such an optional to reference type in most of projects I am working
>on, and when we tried to add contiguous range support - it failed to
>compile pretty seriously because of quite a lot of compile time
>optimization based on forward declarations.
>
>In practice it is also easier to implement input iterator, not to mention
>less code to write:
>
>struct input_iterator
>{
> T* ptr;
> ...
> input_iterator& operator++() { ptr = nullptr; return *this; }
>};
>class optional<T&>
>{
> T* ptr;
> contiguous_iterator begin() const { return ptr; }
> contiguous_iterator end() const { return nullptr; }
>};
>
>comparing to:
>
>struct contiguous_iterator
>{
> T* ptr;
> ...
> contiguous_iterator& operator++() { ++ptr; return *this; } // the line
>that requires T to be defined
> // who would need --, -, +, etc...
>};
>class optional<T&>
>{
> T* ptr;
> contiguous_iterator begin() const { return ptr; }
> contiguous_iterator end() const { return ptr + has_value(); } // the
>next line that requires T to be defined
>};
>
>--
>BR,
>Piotr Nycz

Received on 2024-08-16 17:00:30