LWG3280 and range adaptors
JohelEGP opened this issue · 2 comments
It has come to my attention that, given the resolution to http://wg21.link/LWG3280, the adaptors in the standard, which are specified as views::X(r, args)
being equivalent to X_view{r, args}
will no longer pass their range
and potentially not view
argument r
through views::all
. As part of the resolution, shouldn't the spec say that views::X(r, args)
is equivalent to X_view{views::all(r), args}
?
Let's use views::drop
as representative of range adaptors, and assume the expression E
is an lvalue range
whose cv-unqualified type T
does not model view
. Per [range.drop.adaptor], views::drop{E, F}
is equivalent to drop_view{E, F}
. CTAD selects the explicit deduction guide:
template<class R>
drop_view(R&&, range_difference_t<R>) -> drop_view<all_view<R>>;
since the constraints on the implicit guide derived from the drop_view(V, range_difference_t<V>)
constructor are not satisfied (drop_view<V>
requires view<V>
). Since T
doesn't satisfy view
, all_view<R>
is decltype(ref_view{E})
per [range.all]/2.2). ref_view
as a single explicit deduction guide:
template<class R>
ref_view(R&) -> ref_view<R>;
and no (useful) implicit guides, so decltype(ref_view{E})
is ref_view<remove_reference_t<decltype((E))>>
. Consequently views::drop(E, F)
is equivalent to drop_view<ref_view<remove_reference_t<decltype((E))>>>{E, F}
. Since E
is implicitly convertible to ref_view<remove_reference_t<decltype((E))>>
via ref_view
's converting constructor, the initialization of drop_view<ref_view<remove_reference_t<decltype((E))>>>{E, F}
invokes drop_view
's (V, range_difference_t<V>)
constructor as intended.
Is that clear enough? Is there a hole in the above reasoning?
Thank you. I had forgotten about the deduction guides.