This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3787. `ranges::to`'s template parameter `C` should not be a reference type

Section: 26.5.7.2 [range.utility.conv.to], 26.5.7.3 [range.utility.conv.adaptors] Status: New Submitter: Hewill Kang Opened: 2022-09-25 Last modified: 2022-09-28

Priority: 3

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:

It doesn't make sense for the template parameter `C` of `ranges::to` be a reference, which allows us to write something like `ranges::to<vector<int>&&>(std::move(v))` or `ranges::to<const vector<int>&&>(v)`, we should forbid this.

The proposed resolution constrains the template parameter `C` to be object type to conform to its description: "The range conversion functions construct an object (usually a container) from a range".

[2022-09-28; Reflector poll]

Set priority to 3 after reflector poll. Some suggestions that it should be Mandates: not Constraints:, but no consensus.

Proposed resolution:

This wording is relative to N4917.

1. Modify 26.2 [ranges.syn], header `<ranges>` synopsis, as indicated:

   >     #include <compare>              // see 17.12.1 [compare.syn]
   >     #include <initializer_list>     // see 17.11.2 [initializer.list.syn]
   >     #include <iterator>             // see 25.2 [iterator.synopsis]

   >     namespace std::ranges {
   >       […]
   >       // 26.5.7 [range.utility.conv], range conversions
   >       template<class C, input_range R, class... Args> requires is_object_v<C> && (!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 is_object_v<C> && (!view<C>)
   >         constexpr auto to(Args&&... args);                                              // freestanding
   >       template<template<class...> class C, class... Args>
   >         constexpr auto to(Args&&... args);                                              // freestanding
   >       […]
   >     }

2. Modify 26.5.7.2 [range.utility.conv.to] as indicated:

   >     template<class C, input_range R, class... Args> requires is_object_v<C> && (!view<C>)
   >     constexpr C to(R&& r, Args&&... args);

   > > -1- Returns: An object of type `C` constructed from the elements of `r` in the following manner:

   > > […]

3. Modify 26.5.7.3 [range.utility.conv.adaptors] as indicated:

   >     template<class C, class... Args> requires is_object_v<C> && (!view<C>)
   >       constexpr auto to(Args&&... args);
   >     template<template<class...> class C, class... Args>
   >       constexpr auto to(Args&&... args);

   > > -1- Returns: A range adaptor closure object (26.7.2 [range.adaptor.object]) `f` that is a perfect forwarding call wrapper (22.10.4 [func.require]) with the following properties:

   > > […]