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

### 3278. `join_view<V>::iterator<true>` tries to write through `const join_view` ptr

Section: 26.7.14.2 [range.join.view] Status: Resolved Submitter: Eric Niebler Opened: 2019-09-09 Last modified: 2020-09-06

Priority: 2

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

View all issues with Resolved status.

Discussion:

The non-`const` `join_view::begin()` returns `iterator<simple-view<V>>`. If `simple-view<V>` is `true`, then the iterator stores a `const join_view*` named `parent_`. `iterator::satisfy()` will try to write to `parent_->inner_` if `ref_is_glvalue` is `false`. That doesn't work because the `inner_` field is not marked mutable.

[2019-10 Priority set to 2 after reflector discussion]

[2020-02-10, Prague]

Would be resolved by P1983R0.

[2020-08-21 Issue processing telecon: resolved by P1983R0 §2.4. Status changed: New → Resolved.]

Proposed resolution:

This wording is relative to N4830.

1. Modify 26.7.14.2 [range.join.view], class `template join_view` synopsis, as indicated:

   > [Drafting note: Changing the `join_view<V>::inner_` member to be mutable is safe because this exposition-only member is only used when the `join_view` is single-pass and only modified by operations that invalidate other iterators]

   >     namespace std::ranges {
   >       template<input_range V>
   >         requires view<V> && input_range<range_reference_t<V>>> &&
   >                 (is_reference_v<range_reference_t<V>> ||
   >                 view<range_value_t<V>>)
   >       class join_view : public view_interface<join_view<V>> {
   >       private:
   >         […]
   >         V base_ = V(); // exposition only
   >         mutable all_view<InnerRng> inner_ = // exposition only, present only when
   >                                             // !is_reference_v<InnerRng>
   >           all_view<InnerRng>();
   >       public:
   >         […]
   >       };
   >     }