Created on 2024-05-01.00:00:00 last changed 4 months ago
Proposed resolution:
This wording is relative to N4981.
Modify [range.concat.view] as indicated:
-1- The exposition-only concat-indirectly-readable concept is equivalent to:
template<class Ref, class CRef> concept concat-ref-compatible-with = is_invocable_r_v<CRef, Ref()>; // exposition only template<class Ref, class RRef, class It> concept concat-indirectly-readable-impl = // exposition only requires (const It it) { { *it } ->convertible_toconcat-ref-compatible-with<Ref>; { ranges::iter_move(it) } ->convertible_toconcat-ref-compatible-with<RRef>; }; template<class... Rs> concept concat-indirectly-readable = // exposition only common_reference_with<concat-reference-t<Rs...>&&, concat-value-t<Rs...>&> && common_reference_with<concat-reference-t<Rs...>&&, concat-rvalue-reference-t<Rs...>&&> && common_reference_with<concat-rvalue-reference-t<Rs...>&&, concat-value-t<Rs...> const&> && (concat-indirectly-readable-impl<concat-reference-t<Rs...>, concat-rvalue-reference-t<Rs...>, iterator_t<Rs>> && ...);
[ 2024-06-24; Reflector poll ]
Set priority to 4 after reflector poll. "Proposed resolution loses the existing requirement that the conversion is equality-preserving." "Don't care about rejecting non-movable reference types."
In order to prevent non-equality-preserving behavior of operator* and iter_move, concat_view introduces the concat-indirectly-readable concept, part of which is:
template<class Ref, class RRef, class It> concept concat-indirectly-readable-impl = // exposition only requires (const It it) { { *it } -> convertible_to<Ref>; { ranges::iter_move(it) } -> convertible_to<RRef>; };
This isn't quite right because convertible_to checks is_convertible_v which doesn't understand copy elision. This makes the current concat_view unable to work with ranges whose reference is non-movable prvalue:
auto r = std::views::iota(0, 5) | std::views::transform([](int) { return NonMovable{}; }); auto c1 = std::ranges::concat_view(r); // ill-formed, concat_indirectly_readable not satisfied auto c2 = std::ranges::concat_view(r, r); // ditto
Since std::visit<R> is used in the implementation to perform reference conversion for the underlying iterator, the more accurate one should be is_invocable_r which does understand guaranteed elision.
Note that join_with_view has the same issue because compatible-joinable-ranges requires that the value_type of the inner range and pattern range must satisfy common_with, which always fails for non-movable types. However, this can be automatically resolved by LWG 4074's resolution.History | |||
---|---|---|---|
Date | User | Action | Args |
2024-06-24 12:09:57 | admin | set | messages: + msg14186 |
2024-05-04 17:00:35 | admin | set | messages: + msg14105 |
2024-05-01 00:00:00 | admin | create |