This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
problems with vector::iterator: 1
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: problems with vector::iterator: 1
- From: scott snyder <snyder at fnal dot gov>
- Date: Fri, 05 Nov 1999 14:45:13 -0600
hi -
I've been testing out the new libstdc++, and i've run into some problems
regarding the std::vector iterators. These tests and changes are based
on the september snapshot (2.90.6.1), but from an inspection of the
change logs, it doesn't look like there have been any relevant changes
since then.
If i try to compile the following program using gcc 2.95.2 (on
a i686-pc-linux-gnu platform) and libstdc++:
----------------------------------------------------
#include <vector>
using namespace std::rel_ops;
typedef std::vector<int>::iterator it;
bool foo (it i1, it i2)
{
return i1 != i2;
}
----------------------------------------------------
i get the error:
$ g++ -c -I/usr/local/libstdc++/include/g++-v3 test1.cc
test1.cc: In function `bool foo(__normal_iterator<int *,vector<int,allocator<int> > >, __normal_iterator<int *,vector<int,allocator<int> > >)':
test1.cc:8: ambiguous overload for `it & != it &'
/usr/local/libstdc++/include/g++-v3/bits/stl_iterator.h:1067: candidates are: bool operator !=<int *, int *, vector<int,allocator<int> > >(const __normal_iterator<int *,vector<int,allocator<int> > > &, const __normal_iterator<int *,vector<int,allocator<int> > > &)
/usr/local/libstdc++/include/g++-v3/bits/stl_relops.h:37: bool rel_ops::operator !=<it>(const it &, const it &)
I think the compiler is correct here.
The two relevant declarations are in bits/stl_iterator.h and
bits/stl_reops.h:
template<typename _IteratorL, typename _IteratorR, typename _Container>
bool operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
template <class _Tp>
inline bool operator!=(const _Tp& __x, const _Tp& __y) {
The intention is probably that the first of these should be considered
more specialized, and thus be used. However, that does not happen:
the first of these declarations allows for the two arguments to be of
different types, while the second doesn't. Therefore, by the partial
ordering rules, neither of these templates is more specialized than
the other, and thus, if they both match, there is an ambiguity.
A possible fix is to supply additional specializations for the operators
where the two arguments are the _same_ __normal_iterator type; i.e,
template<typename _Iterator, typename _Container>
bool operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
By the partial ordering rules, this would be considered more specialized
than either of the two above.
Here's a patch to stl_iterator.h which implements this.
1999-11-04 scott snyder <snyder@fnal.gov>
* stl_iterator.h: Supply operator!=, etc. for __normal_iterator
where both arguments are the same type, to avoid amibiguities with
templates from relops.
--- /usr/local/libstdc++/include/g++-v3/bits/stl_iterator.h Sun Oct 24 21:22:51 1999
+++ stl_iterator.h Thu Nov 4 21:28:55 1999
@@ -1094,6 +1094,26 @@
const __normal_iterator<_Iterator, _Container>& __i)
{ return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
+template<typename _Iterator, typename _Container>
+bool operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+{ return !(__lhs == __rhs); }
+
+template<typename _Iterator, typename _Container>
+bool operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+{ return !(__rhs < __lhs); }
+
+template<typename _Iterator, typename _Container>
+bool operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+{ return !(__lhs < __rhs); }
+
+template<typename _Iterator, typename _Container>
+bool operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+{ return __rhs < __lhs; }
+
__STL_END_NAMESPACE
#endif /* __SGI_STL_INTERNAL_ITERATOR_H */
thanks,
sss