C++ Logo

std-proposals

Advanced search

Re: [std-proposals] ranges::to() should prefer iterator_concept over iterator_category

From: Vesselin Atanasov <vesselin.atanasov_at_[hidden]>
Date: Mon, 02 Sep 2024 13:55:19 +0300
OK, thank you for the clarification. I guess I will have to use some
workaround for the time being until libstdc++ adds the missing
constructors.

Regards

On Mon, 2024-09-02 at 09:21 +0100, Jonathan Wakely wrote:
>
>
> On Mon, 2 Sept 2024, 04:42 Vesselin Atanasov via Std-Proposals,
> <std-proposals_at_[hidden]> wrote:
> > Hello,
> >
> > The current C++ standard draft provides a description of
> > ranges:to(),
> > which among other things says:
> >
> > -------------------------------------------
> > 26.5.7.2 ranges​::​to
> > ...
> > (2.1.3) Otherwise, if
> > (2.1.3.1) common_range<R> is true,
> > (2.1.3.2) the qualified-id
> > iterator_traits<iterator_t<R>>​::​iterator_category is valid and
> > denotes a type that models derived_from<input_iterator_tag>, and
> > (2.1.3.3) constructible_from<C, iterator_t<R>, sentinel_t<R>,
> > Args...> is true:
> >
> > C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
> > -------------------------------------------
> >
> > However there are quite a few cases of valid C++20 input iterators
> > that
> > are NOT valid C++17 input iterators, because their post-increment
> > operator returns void. Such input iterators have the
> > iterator_concept
> > typedef but don't have the iterator_category typedef.
> >
> > So if ranges::to() is passed an input range with such an input
> > iterator, it won't be able to construct the container using:
> >
> > C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
> >
> > even though in theory it could if it checked for the
> > iterator_concept
> > typedef.
> >
> > For us who use GCC this problem is additionally aggravated by the
> > fact
> > that GCC's libstdc++ has not implemented
> > P1206R7, Conversions from ranges to containers
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111055
> > So ranges::to() cannot construct the container directly from the
> > range
> > object.
> >
> > And additionally constructing an associative container fails when
> > ranges::to() tries to do that via append, because it calls
> > emplace()
> > with the wrong arguments.
> >
> > What I suggest is amending slightly the way ranges::to() works when
> > it
> > tries to create a container from an iterator+sentinel pair. It
> > should
> > check first the iterator_concept typedef and if it is missing then
> > it
> > should check the iterator_category typedef. This way it will be
> > able to
> > use C++20 input iterators that are not C++17 input iterators.
>
> This doesn't work, because the constructor that you want to use is
> defined in terms of C++17 input iterators. If you pass it arguments
> that are not C++17 input iterators, it might not work.
>
> The correct constructor for this case it's the one that takes the
> from_range tag. We should not change the standard to work around
> missing features in libstdc++. Somebody just needs to add those
> constructors.
>
>
>

Received on 2024-09-02 10:55:24