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.

4559. zip_view, zip_transform_view, and cartesian_product_view should provide reserve_hint

Section: 25.7.25.2 [range.zip.view], 25.7.26.2 [range.zip.transform.view], 25.7.33.2 [range.cartesian.view] Status: New Submitter: Hewill Kang Opened: 2026-03-27 Last modified: 2026-03-27

Priority: Not Prioritized

View other active issues in [range.zip.view].

View all other issues in [range.zip.view].

View all issues with New status.

Discussion:

Although the original paper P2846 gives a reason for not providing reserve_hint for these three views — namely, uncertainty about what the best approach is — it seems to me that providing them is indeed intuitively unambiguous. We don't need to consider the inconsistency between const and non-const overloads because it's not within reasonable ranges.

Given that we provided reserve_hint for concat_view to resolve NB comment FR-025-246, it seems that only these three views are available, but not provided; it's time to do so.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 25.7.25.2 [range.zip.view] as indicated:

    namespace std::ranges {
      […]
      template<input_range... Views>
        requires (view<Views> && ...) && (sizeof...(Views) > 0)
      class zip_view : public view_interface<zip_view<Views...>> {
        […]
        constexpr auto size() requires (sized_range<Views> && ...);
        constexpr auto size() const requires (sized_range<const Views> && ...);
    
        constexpr auto reserve_hint() requires (approximately_sized_range<Views> && ...);
        constexpr auto reserve_hint() const requires (approximately_sized_range<const Views> && ...);
      };
      […]
    }
    
    […]
    constexpr auto size() requires (sized_range<Views> && ...);
    constexpr auto size() const requires (sized_range<const Views> && ...);
    

    -3- Effects: Equivalent to:

    return apply([](auto... sizes) {
      using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
      return ranges::min({CT(sizes)...});
    }, tuple-transform(ranges::size, views_));
    
    constexpr auto reserve_hint() requires (approximately_sized_range<Views> && ...);
    constexpr auto reserve_hint() const requires (approximately_sized_range<const Views> && ...);
    

    -?- Effects: Equivalent to:

    return apply([](auto... sizes) {
      using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
      return ranges::min({CT(sizes)...});
    }, tuple-transform(ranges::reserve_hint, views_));
    
  2. Modify 25.7.26.2 [range.zip.transform.view] as indicated:

    namespace std::ranges {
      […]
      namespace std::ranges {
      template<move_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...>> {
        […]
        constexpr auto size() requires sized_range<InnerView> {
          return zip_.size();
        }
    
        constexpr auto size() const requires sized_range<const InnerView> {
          return zip_.size();
        }
    
        constexpr auto reserve_hint() requires approximately_sized_range<InnerView> {
          return zip_.reserve_hint();
        }
    
        constexpr auto reserve_hint() const requires approximately_sized_range<const InnerView> {
          return zip_.reserve_hint();
        }
      };
      […]
    }
    
    […]
    
    

    
    

  3. Modify 25.7.33.2 [range.cartesian.view] as indicated:

    namespace std::ranges {
      […]
      template<class... Vs>
      concept cartesian-product-is-sized =                  // exposition only
        (sized_range<Vs> && ...);
      
      template<class... Vs>
      concept cartesian-product-is-approximately-sized =    // exposition only
        (approximately_sized_range<Vs> && ...);
      […]
    
      template<input_range First, forward_range... Vs>
        requires (view<First> && ... && view<Vs>)
      class cartesian_product_view : public view_interface<cartesian_product_view<First, Vs...>> {
        […]
        constexpr see below size()
          requires cartesian-product-is-sized<First, Vs...>;
        constexpr see below size() const
          requires cartesian-product-is-sized<const First, const Vs...>;
    
        constexpr see below reserve_hint()
          requires cartesian-product-is-approximately-sized<First, Vs...>;
        constexpr see below reserve_hint() const
          requires cartesian-product-is-approximately-sized<const First, const Vs...>;
      };
      […]
    }
    
    […]
    constexpr see below size()
      requires cartesian-product-is-sized<First, Vs...>;
    constexpr see below size() const
      requires cartesian-product-is-sized<const First, const Vs...>;
    

    -7- The return type is an implementation-defined unsigned-integer-like type.

    -8- Recommended practice: The return type should be the smallest unsigned-integer-like type that is sufficiently wide to store the product of the maximum sizes of all the underlying ranges, if such a type exists.

    -9- Let p be the product of the sizes of all the ranges in bases_.

    -10- Preconditions: p can be represented by the return type.

    -11- Returns: p.

    constexpr see below reserve_hint()
      requires cartesian-product-is-approximately-sized<First, Vs...>;
    constexpr see below reserve_hint() const
      requires cartesian-product-is-approximately-sized<const First, const Vs...>;
    

    -?- The return type is an implementation-defined unsigned-integer-like type.

    -?- Recommended practice: The return type should be the smallest unsigned-integer-like type that is sufficiently wide to store the product of the maximum approximately sizes of all the underlying ranges, if such a type exists.

    -?- Let p be the product of the approximately sizes of all the ranges in bases_.

    -?- Preconditions: p can be represented by the return type.

    -?- Returns: p.