This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/15910] can't compile self defined void distance(std::vector<T>, std::vector<T>)
- From: "bangerth at dealii dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 10 Jun 2004 17:38:09 -0000
- Subject: [Bug libstdc++/15910] can't compile self defined void distance(std::vector<T>, std::vector<T>)
- References: <20040610143911.15910.king.benjamin@mh-hannover.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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