ranges::to
adaptors are underconstrainedSection: 25.5.7.3 [range.utility.conv.adaptors] Status: New Submitter: Hewill Kang Opened: 2023-08-23 Last modified: 2023-11-03
Priority: 3
View all issues with New status.
Discussion:
The ranges::to
adaptor returns a range adaptor closure object that stores a copy of the decayed parameter pack.
#include <ranges>
#include <vector>
struct NonMovable {
NonMovable() = default;
NonMovable(NonMovable&&) = delete;
};
int main() {
auto r = std::ranges::to<std::vector>(NonMovable{}); // hard error in MSVC-STL and libc++
}
Previous resolution [SUPERSEDED]:
This wording is relative to N4958.
Modify 25.2 [ranges.syn], header
<ranges>
synopsis, as indicated:#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] #include <iterator> // see [iterator.synopsis] namespace std::ranges { […] // 25.5.7 [range.utility.conv], range conversions template<class C, input_range R, class... Args> requires (!view<C>>) constexpr C to(R&& r, Args&&... args); // freestanding template<template<class...> class C, input_range R, class... Args> constexpr auto to(R&& r, Args&&... args); // freestanding template<class C, class... Args> requires (!view<C>) && (constructible_from<decay_t<Args>, Args> && ...) constexpr auto to(Args&&... args); // freestanding template<template<class...> class C, class... Args> requires (constructible_from<decay_t<Args>, Args> && ...) constexpr auto to(Args&&... args); // freestanding […] }Modify 25.5.7.3 [range.utility.conv.adaptors] as indicated:
template<class C, class... Args> requires (!view<C>) && (constructible_from<decay_t<Args>, Args> && ...) constexpr auto to(Args&&... args); template<template<class...> class C, class... Args> requires (constructible_from<decay_t<Args>, Args> && ...) constexpr auto to(Args&&... args);-1- Mandates: For the first overload,
-2- Returns: A range adaptor closure object (25.7.2 [range.adaptor.object])C
is a cv-unqualified class type.f
that is a perfect forwarding call wrapper (22.10.4 [func.require]) with the following properties: […]
[2023-11-03; Reflector poll]
Set priority to 3 after reflector poll. Votes split between NAD and using Mandates instead of constraints.
[2023-09-28; Hewill provides alternative wording]
The new wording form is consistent with the current wording, that is, it has a similar structure with 25.7.2 [range.adaptor.object] p1 and 25.7.2 [range.adaptor.object] p8.
Proposed resolution:
This wording is relative to N4958.
Modify 25.5.7.3 [range.utility.conv.adaptors] as indicated:
template<class C, class... Args> requires (!view<C>) constexpr auto to(Args&&... args); template<template<class...> class C, class... Args> constexpr auto to(Args&&... args);-1- Mandates: For the first overload,
-2- Returns: A range adaptor closure object (25.7.2 [range.adaptor.object])C
is a cv-unqualified class type.f
that is a perfect forwarding call wrapper (22.10.4 [func.require]) with the following properties:
(2.1) — It has no target object.
(2.2) — Its bound argument entities
bound_args
consist of objects of typesdecay_t<Args>...
direct-non-list-initialized withstd::forward<Args>(args)...
, respectively.(2.3) — Its call pattern is
to<C>(r, bound_args...)
, wherer
is the argument used in a function call expression off
.-?- Remarks: The expression
to(args...)
is well-formed if and only if the initialization of the bound argument entities of the result, as specified above, are all well-formed.