https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91054
Bug ID: 91054 Summary: replace __gnu_cxx::__normal_iterator<T*, C> by C::iterator in diagnostics Product: gcc Version: 9.1.0 Status: UNCONFIRMED Keywords: diagnostic Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- Libstdc++ uses the __gnu_cxx::__normal_iterator class type for std::vector and std::basic_string iterators, but it obfuscates diagnostics. It would be much nicer to automatically replace the type's real name with the public typedef that users are familiar with. For this invalid program: #include <vector> int main() { std::vector<int> v; auto iter1 = v.begin(); auto iter2 = v.crbegin(); std::distance(iter1, iter2); } G++ prints: iter.cc: In function 'int main()': iter.cc:7:29: error: no matching function for call to 'distance(__gnu_cxx::__normal_iterator<int*, std::vector<int> >&, std::reverse_iterator<__gnu_cxx::__normal_iterator<const int*, std::vector<int> > >&)' 7 | std::distance(iter1, iter2); | ^ In file included from /home/jwakely/gcc/10/include/c++/10.0.0/bits/stl_algobase.h:66, from /home/jwakely/gcc/10/include/c++/10.0.0/vector:60, from iter.cc:1: /home/jwakely/gcc/10/include/c++/10.0.0/bits/stl_iterator_base_funcs.h:138:5: note: candidate: 'template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)' 138 | distance(_InputIterator __first, _InputIterator __last) | ^~~~~~~~ /home/jwakely/gcc/10/include/c++/10.0.0/bits/stl_iterator_base_funcs.h:138:5: note: template argument deduction/substitution failed: iter.cc:7:29: note: deduced conflicting types for parameter '_InputIterator' ('__gnu_cxx::__normal_iterator<int*, std::vector<int> >' and 'std::reverse_iterator<__gnu_cxx::__normal_iterator<const int*, std::vector<int> > >') 7 | std::distance(iter1, iter2); | ^ I think this is easier to read as: iter.cc: In function 'int main()': iter.cc:7:29: error: no matching function for call to 'distance(std::vector<int>::iterator&, std::reverse_iterator<std::vector<int>::const_iterator >&)' 7 | std::distance(iter1, iter2); | ^ In file included from /home/jwakely/gcc/10/include/c++/10.0.0/bits/stl_algobase.h:66, from /home/jwakely/gcc/10/include/c++/10.0.0/vector:60, from iter.cc:1: /home/jwakely/gcc/10/include/c++/10.0.0/bits/stl_iterator_base_funcs.h:138:5: note: candidate: 'template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)' 138 | distance(_InputIterator __first, _InputIterator __last) | ^~~~~~~~ /home/jwakely/gcc/10/include/c++/10.0.0/bits/stl_iterator_base_funcs.h:138:5: note: template argument deduction/substitution failed: iter.cc:7:29: note: deduced conflicting types for parameter '_InputIterator' ('std::vector<int>::iterator' and 'std::reverse_iterator<std::vector<int>::const_iterator >') 7 | std::distance(iter1, iter2); | ^ This is the result of two simplifications: Replace __gnu_cxx::__normal_iterator<const T*, C> with C::const_iterator and replace __gnu_cxx::__normal_iterator<T*, C> with C::iterator. As a further step we could consider replacing std::reverse_iterator<std::C::iterator> with std::C::reverse_iterator, and replacing std::reverse_iterator<std::C::const_iterator> with std::C::const_reverse_iterator. That's more questionable, because it's possible that the user code actually does spell out std::reverse_iterator<std::C::iterator> rather than using the C::reverse_iterator typedef. For the __gnu_cxx::__normal_iterator case users should never be referring to that type, they should only use the public and portable C::iterator and C::const_iterator typedefs.