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.

4125. move_iterator's default constructor should be constrained

Section: 24.5.4.2 [move.iterator], 24.5.4.4 [move.iter.cons] Status: New Submitter: Hewill Kang Opened: 2024-07-22 Last modified: 2024-08-02

Priority: 3

View other active issues in [move.iterator].

View all other issues in [move.iterator].

View all issues with New status.

Discussion:

Although it is unclear why P2325 did not apply to move_iterator, there is implementation divergence among the current libraries (demo):

#include <istream>
#include <iterator>
#include <ranges>

using R = std::ranges::istream_view<int>;
using I = std::ranges::iterator_t<R>;
using MI = std::move_iterator<I>;
static_assert(std::default_initializable<MI>); // libstdc++ passes, libc++ fails

As libc++ additionally requires that its default constructors satisfy is_constructible_v<Iterator>.

Although this is not current standard-conforming behavior, such constraint does make sense since move_iterator only requires the underlying iterator to be input_iterator which may not be default_initializable.

[2024-08-02; Reflector poll]

Set priority to 3 after reflector poll. Five P0 (tentatively rady) votes but one for NAD: "design change, needs paper. Not constraining this seems to be intended by P2325R3. Even if we want to constrain it, why default_initializable rather than just is_constructible_v?"

Proposed resolution:

This wording is relative to N4986.

  1. Modify 24.5.4.2 [move.iterator] as indicated:

    namespace std {
      template<class Iterator>
      class move_iterator {
      public:
        […]
        constexpr move_iterator() requires default_initializable<Iterator> = default;
        […]
      private:
        Iterator current = Iterator();   // exposition only
      };
    }
    
  2. Modify 24.5.4.4 [move.iter.cons] as indicated:

    constexpr move_iterator();
    

    -1- Effects: Value-initializes current.