Skip to content

US276 24.03.1 p1.3 begin/end friends taking rvalues #272

@wg21bot

Description

@wg21bot

24.03.1
24.3.2
24.5.3
24.7.3.1
24.6.3.2
several

Several of the range views define non-template friend function begin/end overloads taking rvalues to satisfy the exposition-only forwarding-range concept. These have a couple of problems. First, the ones for subrange take subrange&&. That means that a const rvalue subrange fails to satisfy forwarding-range, which causes cbegin(subrange{...}) to be ill-formed.

The bigger problem is that since these functions are non-templates, whenever they get added to the overload set, the compiler will try conversions to these types (subrange, ref_view). The attempted conversions could lead to errors in theory.

Finally, class iota_view has iterator that can safely outlive the view that created them, so it too should be given begin/end friend functions that accept rvalues following the same pattern.

Proposed change:
In [range.access.begin]/p1.3, change the poison-pill overloads from:

template<class T> void begin(T&&) = delete;
template/<class T> void begin(initializer_list<T>&&) = delete;

...to:

template<class T> void begin(T&&) = delete;
template<class T> void begin(initializer_list<T>) = delete;

To the synopsis in [range.subrange]/p1, add:

template<class A, class B>
concept same-ish = // exposition only
  same_as<A const, B const>;

In the class synopsis of subrange (same section), change the begin/end friend functions from:

friend constexpr I begin(subrange&& r) { return r.begin(); }
friend constexpr S end(subrange&& r) { return r.end(); }

...to:

friend constexpr I begin(same-ish<subrange> auto && r) { return r.begin(); }
friend constexpr S end(same-ish<subrange> auto && r) { return r.end(); }

In the synopsis of ref_view in [range.ref.view]/p1, change the begin/end friend functions from this:

friend constexpr iterator_t<R> begin(ref_view r)
{ return r.begin(); }
friend constexpr sentinel_t<R> end(ref_view r)
{ return r.end(); }

...to this (editors note: the use of same_as here instead of same-ish is intentional; likewise for the use of pass-by-value):

friend constexpr iterator_t<R> begin(same_as<ref_view> auto r)
{ return r.begin(); }
friend constexpr sentinel_t<R> end(same_as<ref_view> auto r)
{ return r.end(); }

To the class synopsis of iota_view in [range.iota.view], add the following begin/end friend functions:

friend constexpr W begin(same-ish<iota_view> auto && r) { return r.begin(); }
friend constexpr auto end(same-ish<iota_view> auto && r) { return r.end(); }

See ericniebler/stl2#592.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions