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

### 3796. `movable-box` as member should use default-initialization instead of copy-initialization

Section: 26.6.5.2 [range.repeat.view], 26.7.29.2 [range.chunk.by.view] Status: WP Submitter: Hewill Kang Opened: 2022-10-20 Last modified: 2022-11-17

Priority: Not Prioritized

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

View all issues with WP status.

Discussion:

Currently, the member variable `value_` of `repeat_view` is initialized with the following expression:

>     movable-box<W> value_ = W();

which will result in the following unexpected error in libstdc++:

>     #include <ranges>

>     int main() {
>       std::ranges::repeat_view<int> r; // error: could not convert '0' from 'int' to 'std::ranges::__detail::__box<int>'
>     }

This is because the single-argument constructors of the simple version of `movable-box` in libstdc++ are declared as `explicit`, which is different from the conditional `explicit` declared by the `optional`'s constructor, resulting in no visible conversion between those two types.

For MSVC-STL, the simple version of `movable-box` does not provide a single-argument constructor, so this form of initialization will also produce a hard error.

This may be a bug of existing implementations, but we don't need such "copy-initialization", the default-constructed `movable-box` already value-initializes the underlying type.

Simply using default initialization, as most other range adaptors do, guarantees consistency, which also eliminates extra move construction.

[2022-11-01; Reflector poll]

Set status to Tentatively Ready after nine votes in favour during reflector poll.

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4917.

1. Modify 26.6.5.2 [range.repeat.view] as indicated:

   >     namespace std::ranges {
   >       template<move_constructible W, semiregular Bound = unreachable_sentinel_t>
   >         requires (is_object_v<W> && same_as<W, remove_cv_t<W>> &&
   >                   (is-integer-like<Bound> || same_as<Bound, unreachable_sentinel_t>))
   >        class repeat_view : public view_interface<repeat_view<W, Bound>> {
   >        private:
   >          // 26.6.5.3 [range.repeat.iterator], class repeat_view::iterator
   >          struct iterator;                            // exposition only

   >          movable-box<W> value_ = W();                // exposition only, see 26.7.3 [range.move.wrap]
   >          Bound bound_ = Bound();                     // exposition only
   >          […]
   >        };
   >        […]
   >     }

2. Modify 26.7.29.2 [range.chunk.by.view] as indicated:

   >     namespace std::ranges {
   >       template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
   >         requires view<V> && is_object_v<Pred>
   >       class chunk_by_view : public view_interface<chunk_by_view<V, Pred>> {
   >         V base_ = V();                                          // exposition only
   >         movable-box<Pred> pred_ = Pred();                       // exposition only

   >         // 26.7.29.3 [range.chunk.by.iter], class chunk_by_view::iterator
   >         class iterator;                                         // exposition only
   >         […]
   >       };
   >       […]
   >     }