This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/15910] can't compile self defined void distance(std::vector<T>, std::vector<T>)


------- Additional Comments From bangerth at dealii dot org  2004-06-10 17:38 -------
Alright, so here things go: in libstdc++ we have 
 
namespace std{ 
    template<typename _InputIterator> 
    inline typename iterator_traits<_InputIterator>::difference_type 
    distance(_InputIterator __first, _InputIterator __last) 
    { 
 
      return std::__distance(__first, __last, 
        std::__iterator_category(__first)); 
    } 
} 
 
Clearly this is a match for the call regarding the arguments to the 
function. There is a general iterator_traits template: 
 
  template<typename _Iterator> 
    struct iterator_traits 
    { 
      typedef typename _Iterator::iterator_category iterator_category; 
      typedef typename _Iterator::value_type value_type; 
      typedef typename _Iterator::difference_type difference_type; 
      typedef typename _Iterator::pointer pointer; 
      typedef typename _Iterator::reference reference; 
    }; 
 
In this case, we will instantiate it with _Iterator=std::vector<double> 
(oh, well, not really an iterator, but how can the compiler know). Now, 
in order to substitute all template arguments to std::distance correctly, 
_Iterator needs to have a difference_type typedef -- which indeed 
std::vector has, namely ptrdiff_t. So we have a match in std::distance, 
and this is what the compiler picks. So far everything is alright. 
 
The next step is that the compiler has to actually compile std::distance 
for this odd template argument that should be, but is not an iterator. 
It fails when finding out the iterator category: 
  __iterator_category(__first) 
This is defined as follows: 
  template<typename _Iter> 
    inline typename iterator_traits<_Iter>::iterator_category 
    __iterator_category(const _Iter&) 
    { return typename iterator_traits<_Iter>::iterator_category(); } 
We use again the general iterator_traits class template which 
yields that  
  iterator_category == _Iterator::iterator_category 
with _Iterator==std::vector. Here, we fail, because this local 
type doesn't exist, so we don't find a matching function 
  __iterator_category 
to call. This is exactly the compiler's error message. I think it 
is alright, though it may be somewhat confusing. 
 
I think there is not much we can do about this -- what the user would 
like is of course that std::distance is rejected right away, but we could 
only do this by putting more checks into the function signature (via SFINAE) 
that the type that was passed is indeed an iterator. Given the wide 
variability of iterator types, I fear that there is not very much we can 
do about things at this point. 
 
Giovanni, are you convinced that this isn't really a gcc problem? 
 
W. 

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15910


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]