https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97600
--- Comment #2 from Patrick Palka <ppalka at gcc dot gnu.org> --- I think all views whose begin()/end() has a placeholder return type and performs direct initialization of a _Iterator/_Sentinel from *this are affected by some variant of this issue. A library-side workaround would be to templatize view_interface::operator bool() like so: diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index cc50e2ad4e4..8563a5dfcb0 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -86,13 +86,15 @@ namespace ranges empty() const requires forward_range<const _Derived> { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); } - constexpr explicit - operator bool() requires requires { ranges::empty(_M_derived()); } - { return !ranges::empty(_M_derived()); } - - constexpr explicit - operator bool() const requires requires { ranges::empty(_M_derived()); } - { return !ranges::empty(_M_derived()); } + template<same_as<bool> _Tp> + constexpr explicit + operator _Tp() requires requires { ranges::empty(_M_derived()); } + { return !ranges::empty(_M_derived()); } + + template<same_as<bool> _Tp> + constexpr explicit + operator _Tp() const requires requires { ranges::empty(_M_derived()); } + { return !ranges::empty(_M_derived()); } constexpr auto data() requires contiguous_iterator<iterator_t<_Derived>> So that when we considering this conversion function in step 5, we deduce _Tp=_Iterator and short circuit satisfaction of the conversion function's associated constraints in step 6.