https://gcc.gnu.org/g:5fa283f51f67dedd95841a2a69d8964a73de3890
commit r17-5000-g5fa283f51f67dedd95841a2a69d8964a73de3890 Author: Tomasz KamiĆski <[email protected]> Date: Thu Oct 8 15:14:39 2026 +0200 libstdc++: Constrain move_iterator default constructor. This implements LWG4125, "move_iterator's default constructor should be constrained". As for other operations on move_iterator, the constrain is only when concepts are available (__glibcxx_concepts). libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (move_iterator::move_iterator()) [__glibcxx_concepts]: Constrain with default_initializable. * testsuite/24_iterators/move_iterator/default_init.cc: New test. Reviewed-by: Jonathan Wakely <[email protected]> Diff: --- libstdc++-v3/include/bits/stl_iterator.h | 5 +++++ .../24_iterators/move_iterator/default_init.cc | 25 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index bcc22c50de57..c8418266e0c8 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1508,8 +1508,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __base_ref>; #endif + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4125. move_iterator's default constructor should be constrained _GLIBCXX17_CONSTEXPR move_iterator() +#ifdef __glibcxx_concepts + requires default_initializable<_Iterator> +#endif : _M_current() { } explicit _GLIBCXX17_CONSTEXPR diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/default_init.cc b/libstdc++-v3/testsuite/24_iterators/move_iterator/default_init.cc new file mode 100644 index 000000000000..5134ef570093 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/default_init.cc @@ -0,0 +1,25 @@ +// { dg-do compile { target c++20 } } + +#include <iterator> + +struct no_default_init_iterator +{ + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + + no_default_init_iterator() = delete; + no_default_init_iterator(no_default_init_iterator&&) = default; + no_default_init_iterator& operator=(no_default_init_iterator&&) = default; + + no_default_init_iterator& operator++(); + no_default_init_iterator operator++(int); + int& operator*() const; + + bool operator==(const no_default_init_iterator&) const; +}; + +static_assert( std::is_default_constructible_v<std::move_iterator<int*>> ); +static_assert( !std::is_default_constructible_v<std::move_iterator<no_default_init_iterator>> ); + +
