Section: 26.5.7.2 [range.utility.conv.to] Status: New Submitter: Hewill Kang Opened: 2023-11-25 Last modified: 2023-11-25 19:07:03 UTC
Priority: Not Prioritized
View other active issues in [range.utility.conv.to].
View all other issues in [range.utility.conv.to].
View all issues with New status.
Discussion:
Unlike other branches that return a prvalue C, this branch's C is returned by elidable move, indicating that C needs to be move constructible (demo):
#include <ranges>
#include <vector>
struct nonmovable {
nonmovable() = default;
nonmovable(const nonmovable&) = delete;
nonmovable& operator=(const nonmovable&) = delete;
};
template<class T>
struct nonmovable_vector : std::vector<T>, nonmovable { };
int main() {
int arr[] = {42};
auto v = std::ranges::to<nonmovable_vector<int>>(arr); // hard error
}
Proposed resolution:
This wording is relative to N4964.
Modify 26.5.7.2 [range.utility.conv.to] as indicated:
template<class C, input_range R, class... Args> requires (!view<C>) constexpr C to(R&& r, Args&&... args);-1- Mandates: C is a cv-unqualified class type.
-2- Returns: An object of type C constructed from the elements of r in the following manner:
(2.1) — If C does not satisfy input_range or convertible_to<range_reference_t<R>, range_value_t<C>> is true:
(2.1.1) — […]
(2.1.2) — […]
(2.1.3) — […]
(2.1.4) — Otherwise, if
(2.1.4.?) — move_constructible<C> is true,
(2.1.4.1) — constructible_from<C, Args...> is true, and
(2.1.4.2) — container-insertable<C, range_reference_t<R>> is true:
C c(std::forward<Args>(args)...); if constexpr (sized_range<R> && reservable-container<C>) c.reserve(static_cast<range_size_t<C>>(ranges::size(r))); ranges::copy(r, container-inserter<range_reference_t<R>>(c));(2.1.5) — Otherwise, the program is ill-formed.
(2.2) — […]
(2.3) — Otherwise, the program is ill-formed.