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