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.
join_view incorrectly stores inner rangeSection: 25.7.14.2 [range.join.view], 25.7.15.2 [range.join.with.view] Status: New Submitter: Hewill Kang Opened: 2025-03-06 Last modified: 2025-10-23
Priority: 3
View other active issues in [range.join.view].
View all other issues in [range.join.view].
View all issues with New status.
Discussion:
When the inner range is a prvalue, join_view removes its cv-qualifiers
and stores it in the propagating-cache, which is not quite right as the inner range may
only be const-iterable (demo):
#include <ranges>
struct R {
  int* begin() = delete;
  int* end() = delete;
  const int* begin() const;
  const int* end() const;
};
int main() {
  auto r = std::views::iota(0, 5)
         | std::views::transform([](int) -> const R { return {}; })
         | std::views::join;
  auto b = r.begin(); // hard error
}
The proposed resolution preserves the inner range's original qualifiers, which is consistent with how
cache_latest_view stores the reference when it is a prvalue.
The same goes for join_with_view.
[2025-10-23; Reflector poll.]
Set priority to 3 after reflector poll.
Lot of NAD votes. This type satisfies, but does not model range.
Proposed resolution:
This wording is relative to N5001.
Modify 25.7.14.2 [range.join.view] as indicated:
namespace std::ranges {
  template<input_range V>
    requires view<V> && input_range<range_reference_t<V>>>
  class join_view : public view_interface<join_view<V>> {
  private:
    using InnerRng = range_reference_t<V>;                  // exposition only
    […]
    non-propagating-cache<remove_cv_t<InnerRng>> inner_;    // exposition only, present only
                                                            // if is_reference_v<InnerRng> is false
  public:
    […]
  };
  […]
}
Modify 25.7.15.2 [range.join.with.view] as indicated:
namespace std::ranges {
  […]
  template<input_range V, forward_range Pattern>
    requires view<V> && input_range<range_reference_t<V>>
          && view<Pattern>
          && concatable<range_reference_t<V>, Pattern>
  class join_with_view : public view_interface<join_with_view<V, Pattern>> {
    using InnerRng = range_reference_t<V>;                 // exposition only
    […]
    non-propagating-cache<remove_cv_t<InnerRng>> inner_;   // exposition only, present only
                                                           // if is_reference_v<InnerRng> is false
    […]
  public:
    […]
  };
  […]
}