ranges::to's recursion branch may be ill-formed
Hewill Kang

Created on 2023-08-23.00:00:00 last changed 3 weeks ago


Date: 2023-11-07.22:39:32

Proposed resolution:

This wording is relative to N4958.

  1. Modify [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:

    1. (2.1) — If C does not satisfy input_range or convertible_to<range_reference_t<R>, range_value_t<C>> is true:

      1. […]

    2. (2.2) — Otherwise, if input_range<range_reference_t<R>> is true:

      to<C>(ref_view(r) | views::transform([](auto&& elem) {
        return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));
      }), std::forward<Args>(args)...);
    3. (2.3) — Otherwise, the program is ill-formed.

Date: 2023-11-07.22:39:32

[ Kona 2023-11-07; move to Ready ]

Date: 2023-11-15.00:00:00

[ 2023-11-03; Reflector poll ]

Set priority to 3 after reflector poll. "Should be std::forward<R>(r) instead?"

Date: 2023-08-23.00:00:00

When r is a nested range, ranges::to constructs the object recursively through r | views::transform(...).

However, the expression is ill-formed when the type of lvalue r does not model viewable_range (demo):

#include <ranges>
#include <vector>
#include <list>

int main() {
  std::vector<std::vector<int>> v;
  auto r = std::views::all(std::move(v));
  auto l = std::ranges::to<std::list<std::list<int>>>(r); // hard error in MSVC-STL and libc++
Date User Action Args
2023-11-07 22:39:32adminsetmessages: + msg13829
2023-11-07 22:39:32adminsetstatus: new -> ready
2023-11-03 18:08:28adminsetmessages: + msg13807
2023-09-24 10:08:01adminsetmessages: + msg13736
2023-08-23 00:00:00admincreate