https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119469
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
We define iter_rvalue_reference_t<F&> in terms of remove_reference_t<F&>&&
instead of decltype(std::move(*std::declval<F&>())) and they're not the same.
But I don't understand why.
This fixes iter_rvalue_reference_t (and a comment typo):
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -133,12 +133,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __result<_Tp>
{ using type = decltype(iter_move(std::declval<_Tp>())); };
- // Otherwise, if *E if an lvalue, use std::move(*E).
+ // Otherwise, if *E is an lvalue, use std::move(*E).
template<typename _Tp>
requires (!__adl_imove<_Tp>)
&& is_lvalue_reference_v<__iter_ref_t<_Tp>>
struct __result<_Tp>
- { using type = remove_reference_t<__iter_ref_t<_Tp>>&&; };
+ { using type = decltype(std::move(*std::declval<_Tp>())); };
template<typename _Tp>
static constexpr bool
But I'd like to understand why the original code wasn't equivalent.