Created on 2022-06-10.00:00:00 last changed 4 months ago
Proposed resolution:
This wording is relative to N4910.
Modify [range.zip.transform.view] as indicated:
namespace std::ranges { template<copy_constructible F, input_range... Views> requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> && regular_invocable<F&, range_reference_t<Views>...> && can-reference<invoke_result_t<F&, range_reference_t<Views>...>> class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> { copyable-box<F> fun_; // exposition only zip_view<Views...> zip_; // exposition only […] public: zip_transform_view() = default; constexprexplicitzip_transform_view(F fun, Views... views); […] }; […] }constexprexplicitzip_transform_view(F fun, Views... views);-1- Effects: Initializes fun_ with std::move(fun) and zip_ with std::move(views)....
Modify [range.adjacent.transform.view] as indicated:
namespace std::ranges { template<forward_range V, copy_constructible F, size_t N> requires view<V> && (N > 0) && is_object_v<F> && regular_invocable<F&, REPEAT(range_reference_t<V>, N)...> && can-reference<invoke_result_t<F&, REPEAT(range_reference_t<V>, N)...>> class adjacent_transform_view : public view_interface<adjacent_transform_view<V, F, N>> { copyable-box<F> fun_; // exposition only adjacent_view<V, N> inner_; // exposition only […] public: adjacent_transform_view() = default; constexprexplicitadjacent_transform_view(V base, F fun); […] }; […] }constexprexplicitadjacent_transform_view(V base, F fun);-1- Effects: Initializes fun_ with std::move(fun) and inner_ with std::move(base).
Modify [range.chunk.view.input] as indicated:
namespace std::ranges { […] template<view V> requires input_range<V> class chunk_view : public view_interface<chunk_view<V>> { V base_ = V(); // exposition only range_difference_t<V> n_ = 0; // exposition only […] public: chunk_view() requires default_initializable<V> = default; constexprexplicitchunk_view(V base, range_difference_t<V> n); […] }; […] }constexprexplicitchunk_view(V base, range_difference_t<V> n);-1- Preconditions: n > 0 is true.
-2- Effects: Initializes base_ with std::move(base) and n_ with n.
Modify [range.chunk.view.fwd] as indicated:
namespace std::ranges { template<view V> requires forward_range<V> class chunk_view<V> : public view_interface<chunk_view<V>> { V base_ = V(); // exposition only range_difference_t<V> n_ = 0; // exposition only […] public: chunk_view() requires default_initializable<V> = default; constexprexplicitchunk_view(V base, range_difference_t<V> n); […] }; }constexprexplicitchunk_view(V base, range_difference_t<V> n);-1- Preconditions: n > 0 is true.
-2- Effects: Initializes base_ with std::move(base) and n_ with n.
Modify [range.slide.view] as indicated:
namespace std::ranges { […] template<forward_range V> requires view<V> class slide_view : public view_interface<slide_view<V>> { V base_ = V(); // exposition only range_difference_t<V> n_ = 0; // exposition only […] public: slide_view() requires default_initializable<V> = default; constexprexplicitslide_view(V base, range_difference_t<V> n); […] }; […] }constexprexplicitslide_view(V base, range_difference_t<V> n);-1- Effects: Initializes base_ with std::move(base) and n_ with n.
Modify [range.chunk.by.view] as indicated:
namespace std::ranges { template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred> requires view<V> && is_object_v<Pred> class chunk_by_view : public view_interface<chunk_by_view<V, Pred>> { V base_ = V(); // exposition only copyable-box<Pred> pred_ = Pred(); // exposition only […] public: chunk_by_view() requires default_initializable<V> && default_initializable<Pred> = default; constexprexplicitchunk_by_view(V base, Pred pred); […] }; […] }constexprexplicitchunk_by_view(V base, Pred pred);-1- Effects: Initializes base_ with std::move(base) and pred_ with std::move(pred).
[ 2024-06-24 Status changed: Tentatively NAD → NAD. ]
P2711R1 was approved in February 2023, confirming that these constructors should be explicit.
[ 2023-01-24; LEWG in Kona ]
Use alternative approach in P2711 instead.
[ 2022-06-21; Reflector poll ]
Set priority to 4 after reflector poll. Send to LEWG.
[ 2022-06-11; Daniel comments ]
Another possible candidate could be [range.take.while.sentinel]'s
constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
All C++20 range adaptors' non-single-argument constructors are not declared as explicit, which makes the following initialization well-formed:
std::vector v{42}; std::ranges::take_view r1 = {v, 1}; std::ranges::filter_view r2 = {v, [](int) { return true; }};
However, the non-single-argument constructors of C++23 range adaptors, except for join_with_view, are all explicit, which makes us no longer able to
std::ranges::chunk_view r1 = {v, 1}; // ill-formed std::ranges::chunk_by_view r2 = {v, [](int, int) { return true; }}; // ill-formed
This seems unnecessary since I don't see the observable benefit of preventing this. In the standard, non-single-argument constructors are rarely specified as explicit unless it is really undesirable, I think the above initialization is what the user expects since it's clearly intentional, and I don't see any good reason to reject it from C++23.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-06-24 17:32:57 | admin | set | messages: + msg14208 |
2023-01-24 10:14:05 | admin | set | messages: + msg13213 |
2023-01-24 10:14:05 | admin | set | status: lewg -> nad |
2022-06-21 11:51:20 | admin | set | messages: + msg12526 |
2022-06-21 11:51:20 | admin | set | status: new -> lewg |
2022-06-11 19:34:19 | admin | set | messages: + msg12500 |
2022-06-11 19:00:25 | admin | set | messages: + msg12499 |
2022-06-10 00:00:00 | admin | create |