[libcxx-commits] [libcxx] [libc++] LWG4125: `move_iterator`'s default constructor should be constrained (PR #206427)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 29 01:28:10 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

<details>
<summary>Changes</summary>

- The default constructor is not yet defaulted as indicated by the resolution of LWG4125, because the effects of defaulted-ness is not strictly observable. Also, it's arguable not feasible to use default member initializer `= _Iter()` because it might cause non-conforming behavior in pre-C++17 modes, due to lack of guaranteed RVO.
- In the test file, `NoDefaultCtr` is replaced with a proper iterator type `cpp20_input_iterator<int*>` to make the test more pedantically conforming.

Fixes #<!-- -->204442.

---
Full diff: https://github.com/llvm/llvm-project/pull/206427.diff


3 Files Affected:

- (modified) libcxx/docs/Status/Cxx29Issues.csv (+1-1) 
- (modified) libcxx/include/__iterator/move_iterator.h (+2-2) 
- (modified) libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp (+27-10) 


``````````diff
diff --git a/libcxx/docs/Status/Cxx29Issues.csv b/libcxx/docs/Status/Cxx29Issues.csv
index d9e245a9a11c0..13056a97782df 100644
--- a/libcxx/docs/Status/Cxx29Issues.csv
+++ b/libcxx/docs/Status/Cxx29Issues.csv
@@ -1,7 +1,7 @@
 "Issue #","Issue Name","Meeting","Status","First released version","GitHub issue","Notes"
 "`LWG3417 <https://wg21.link/LWG3417>`__","Missing ``volatile`` atomic deprecations","2026-06 (Brno)","","","`#204440 <https://github.com/llvm/llvm-project/issues/204440>`__",""
 "`LWG4121 <https://wg21.link/LWG4121>`__","``ranges::to`` constructs associative containers via ``c.emplace(c.end(), *it)``","2026-06 (Brno)","","","`#204441 <https://github.com/llvm/llvm-project/issues/204441>`__",""
-"`LWG4125 <https://wg21.link/LWG4125>`__","``move_iterator``'s default constructor should be constrained","2026-06 (Brno)","","","`#204442 <https://github.com/llvm/llvm-project/issues/204442>`__",""
+"`LWG4125 <https://wg21.link/LWG4125>`__","``move_iterator``'s default constructor should be constrained","2026-06 (Brno)","|Complete|","23","`#204442 <https://github.com/llvm/llvm-project/issues/204442>`__",""
 "`LWG4158 <https://wg21.link/LWG4158>`__","``packaged_task::operator=`` should abandon its shared state","2026-06 (Brno)","","","`#204443 <https://github.com/llvm/llvm-project/issues/204443>`__",""
 "`LWG4182 <https://wg21.link/LWG4182>`__","Definition of ``NULL`` is too broad","2026-06 (Brno)","","","`#204444 <https://github.com/llvm/llvm-project/issues/204444>`__",""
 "`LWG4218 <https://wg21.link/LWG4218>`__","Constraint recursion in ``basic_const_iterator``'s relational operators due to ADL + CWG 2369","2026-06 (Brno)","","","`#204445 <https://github.com/llvm/llvm-project/issues/204445>`__",""
diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h
index c42f4cb53e9a8..aa5570c018737 100644
--- a/libcxx/include/__iterator/move_iterator.h
+++ b/libcxx/include/__iterator/move_iterator.h
@@ -13,6 +13,7 @@
 #include <__compare/compare_three_way_result.h>
 #include <__compare/three_way_comparable.h>
 #include <__concepts/assignable.h>
+#include <__concepts/constructible.h>
 #include <__concepts/convertible_to.h>
 #include <__concepts/derived_from.h>
 #include <__concepts/same_as.h>
@@ -27,7 +28,6 @@
 #include <__type_traits/conditional.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_assignable.h>
-#include <__type_traits/is_constructible.h>
 #include <__type_traits/is_convertible.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/is_same.h>
@@ -122,7 +122,7 @@ class move_iterator
 
 #if _LIBCPP_STD_VER >= 20
   _LIBCPP_HIDE_FROM_ABI constexpr move_iterator()
-    requires is_constructible_v<_Iter>
+    requires default_initializable<_Iter>
       : __current_() {}
 
   template <class _Up>
diff --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
index d095182c560d8..00512fa2f3dad 100644
--- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
@@ -10,11 +10,8 @@
 
 // move_iterator
 
-// move_iterator();
-//
-//  constexpr in C++17
-//
-//  requires the underlying iterator to be default-constructible (extension).
+// constexpr move_iterator();                   // constexpr since C++17
+//   requires default_initializable<Iterator>;  // since C++20
 
 #include <iterator>
 
@@ -22,13 +19,33 @@
 #include "test_macros.h"
 #include "test_iterators.h"
 
-#if TEST_STD_VER > 17
-struct NoDefaultCtr : forward_iterator<int*> {
-  NoDefaultCtr() = delete;
+#if TEST_STD_VER >= 20
+class constable_iter {
+public:
+  using iterator_category = std::input_iterator_tag;
+  using difference_type   = std::ptrdiff_t;
+  using value_type        = char;
+
+  constable_iter() = default;
+
+  template <class U = constable_iter>
+  const constable_iter& operator=(const std::type_identity_t<constable_iter>&) const;
+
+  char operator*() const;
+
+  const constable_iter& operator++() const;
+  void operator++(int) const;
+
+private:
+  char payload_; // making `const constable_iter` value-initializable but not default-initializable
 };
+static_assert(std::is_default_constructible_v<const constable_iter>);
+static_assert(!std::default_initializable<const constable_iter>);
+static_assert(std::input_iterator<const constable_iter>);
 
-LIBCPP_STATIC_ASSERT( std::is_default_constructible_v<std::move_iterator<forward_iterator<int*>>>);
-LIBCPP_STATIC_ASSERT(!std::is_default_constructible_v<std::move_iterator<NoDefaultCtr>>);
+static_assert(std::is_default_constructible_v<std::move_iterator<forward_iterator<int*>>>);
+static_assert(!std::is_default_constructible_v<std::move_iterator<cpp20_input_iterator<int*>>>);
+static_assert(!std::is_default_constructible_v<std::move_iterator<const constable_iter>>);
 #endif
 
 template <class It>

``````````

</details>


https://github.com/llvm/llvm-project/pull/206427


More information about the libcxx-commits mailing list