https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95983

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2020-07-08
           Assignee|unassigned at gcc dot gnu.org      |redi at gcc dot gnu.org
             Status|UNCONFIRMED                 |ASSIGNED

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to ensadc from comment #0)
> It seems that in this case, `iter_difference_t` is treated as an alias of
> `std::iterator_traits<std::counted_iterator<It>>::difference_type` (which
> doesn't exist), because libstdc++ defines a specialization of
> `std::iterator_traits<std::counted_iterator<It>>`.

That specialization is required, see [counted.iterator], and we define it
correctly.

This seems to be a defect in C++20. iter_difference_t<I> is required to use
iterator_traits<I>::difference_type if iterator_traits<I> is specialized, which
it is here. But the specialization doesn't define difference_type.

It doesn't matter that incrementable_traits<I>::difference_type is defined,
because it doesn't get used.

I think the fix is (untested):

--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -2141,16 +2141,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       iter_difference_t<_It> _M_length = 0;
     };

-  template<typename _It>
-    struct incrementable_traits<counted_iterator<_It>>
-    {
-      using difference_type = iter_difference_t<_It>;
-    };
-
   template<input_iterator _It>
     struct iterator_traits<counted_iterator<_It>> : iterator_traits<_It>
     {
       using pointer = void;
+      using difference_type = iter_difference_t<_It>;
     };
 #endif // C++20

Reply via email to