This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


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

problems with vector::iterator: 1



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

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