iterator - Operator != is ambiguous for std::reverse_iterator c++ -
i working on container implements own iterator, using std::reverse_iterator<> reverse iteration functionality. can assign reverse iterator rend or rbegin, when try access of functionality (such != or ==) this:
1 intellisense: more 1 operator "!=" matches these operands: function template "bool std::operator!=(const std::reverse_iterator<_ranit1> &_left, const std::reverse_iterator<_ranit2> &_right)" function template "bool avl::operator!=(const tree &left, const tree &right)" operand types are: std::reverse_iterator<avl::avl_iterator<avl::avltree<char, int, std::less<char>, std::allocator<std::pair<const char, int>>>>> != std::reverse_iterator<avl::avl_iterator<avl::avltree<char, int, std::less<char>, std::allocator<std::pair<const char, int>>>>> my iterator operator overloads:
bool operator == ( const avl_iterator& rhs ) const { return ( _node == rhs._node); } bool operator != ( const avl_iterator& rhs ) const { return ( _node != rhs._node); } and implementation of reverse iterator
typedef typename avl_iterator< tree > iterator; typedef typename const_avl_iterator< tree > const_iterator; typedef typename std::reverse_iterator<iterator> reverse_iterator; typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator; and iterator typedefs:
typedef typename tree::node node; typedef typename tree::node_ptr node_ptr; typedef typename tree::value_type* pointer;// std reverse iterator typedef typename tree::value_type& reference; typedef typename tree::const_node_ptr const_node_ptr; typedef typename tree::utilities utilities; typedef typename tree::value_type value_type; typedef std::bidirectional_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; how i'm using operator
avltree<char,int> mytree; mytree.insert(std::pair<char,int>('a',1)); mytree.insert(std::pair<char,int>('b',2)); mytree.insert(std::pair<char,int>('c',3)); avltree<char,int>::reverse_iterator rit = mytree.rbegin(); for(; rit != mytree.rend(); ++rit) //fails on line { } and iterator class (const_iterator same thing const value_type)
template <class tree> class avl_iterator { public: typedef typename tree::node node; typedef typename tree::node_ptr node_ptr; typedef typename tree::value_type* pointer;// std reverse iterator typedef typename tree::value_type& reference; typedef typename tree::const_node_ptr const_node_ptr; typedef typename tree::utilities utilities; typedef typename tree::value_type value_type; typedef std::bidirectional_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; private: friend class const_avl_iterator<tree>; node_ptr _node; public: avl_iterator() : _node() { } avl_iterator( const node_ptr node ) : _node ( node ) { } avl_iterator( const avl_iterator& iterator ) { (*this) = iterator; } ~avl_iterator() { _node = null; } avl_iterator& operator=(const avl_iterator& rhs) { _node = rhs._node; return (*this); } avl_iterator& operator=(const const_avl_iterator<tree>& rhs) { _node = rhs._node; return (*this); } bool operator == ( const avl_iterator& rhs ) const { return ( _node == rhs._node); } bool operator != ( const avl_iterator& rhs ) const { return ( _node != rhs._node); } avl_iterator& operator++() { _node = utilities::next_node( _node ); return (*this); } avl_iterator operator ++( int ) { avl_iterator temp(*this); ++(*this); return(temp); } avl_iterator& operator -- () { _node = utilities::prev_node( _node ); return (*this); } avl_iterator operator -- ( int ) { avl_iterator temp(*this); --(*this); return(temp); } value_type& operator * () const { assert( ! utilities::is_header( _node ) ); return _node->_value; } value_type* operator -> () const { assert( ! utilities::is_header( _node ) ); return &_node->_value; } }; and tree class:
template < class key, class type, class traits = std::less<key>, class allocator = std::allocator<std::pair<key const, type>> > class avltree { private: typedef avltree< key, type, traits, allocator> tree; public: typedef std::pair<const key, type> value_type; typedef allocator allocator_type; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::reference reference; typedef key key_type; typedef type mapped_type; typedef traits key_compare; typedef typename avl_node< tree > node; typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; typedef typename avl_utilities< tree > utilities; typedef typename avl_iterator< tree > iterator; typedef typename const_avl_iterator< tree > const_iterator; typedef typename std::reverse_iterator<iterator> reverse_iterator; typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator; private: node_ptr _header; std::size_t _size; key_compare _comparer; allocator_type _alloc; public: //c'tors , d'tors //******************************************************* //iterators //******************************************************* iterator begin() { return iterator( node::get_left( _header ) ); } const_iterator begin() const { return const_iterator( node::get_left( _header ) ); } const_iterator cbegin() const { return const_iterator( node::get_left( _header ) ); } iterator end() { return iterator( _header ); } const_iterator end() const { return const_iterator( _header ); } const_iterator cend() const { return const_iterator( _header ); } reverse_iterator rbegin() { return reverse_iterator( _header ); } const_reverse_iterator rbegin() const { return const_reverse_iterator( _header ); } const_reverse_iterator crbegin() const { return const_reverse_iterator( _header ); } reverse_iterator rend() { return reverse_iterator( node::get_left( _header ) ); } const_reverse_iterator rend() const { return const_reverse_iterator( node::get_left( _header ) ); } const_reverse_iterator crend() const { return const_reverse_iterator( node::get_left( _header ) ); } bool operator==(const tree& right) { if(_size != right.size()) { return false; } const_iterator lhs = cbegin(); const_iterator rhs = right.cbegin(); while(lhs != cend() && rhs != right.cend() ) { if(lhs->first != rhs->first || lhs->second != rhs->second) { return false; } ++lhs; ++rhs; } return true; } bool operator!=(const tree& right) { return (!(*this == right)); } bool operator<(const tree& right) { const_iterator lhs = cbegin(); const_iterator rhs = right.cbegin(); while(lhs != cend() && rhs != right.cend() ) { if(lhs->first != rhs->first || lhs->second != rhs->second) { if(lhs->first < rhs->first || lhs->second < rhs->second) { return true; } } ++lhs; ++rhs; } return false; } bool operator>(const tree& right) { return ( right < *this ); } bool operator<=(const tree& right) { return ( !(right < *this) ); } bool operator>=(const tree& right) { return ( !(*this < right) ); } }; //******************************************************* //relation operators //******************************************************* template<class tree> bool operator==(const tree& left,const tree& right) { if(left.size() != right.size()) { return false; } tree::const_iterator lhs = left.cbegin(); tree::const_iterator rhs = right.cbegin(); while(lhs != left.cend() && rhs != right.cend() ) { if(lhs->first != rhs->first || lhs->second != rhs->second) { return false; } ++lhs; ++rhs; } return true; } template<class tree> bool operator!=(const tree& left,const tree& right) { return (!(left == right)); } template<class tree> bool operator<(const tree& left,const tree& right) { tree::const_iterator lhs = left.cbegin(); tree::const_iterator rhs = right.cbegin(); while(lhs != left.cend() && rhs != right.cend() ) { if(lhs->first != rhs->first || lhs->second != rhs->second) { if(lhs->first < rhs->first || lhs->second < rhs->second) { return true; } } ++lhs; ++rhs; } return false; } template<class tree> bool operator>(const tree& left,const tree& right) { return ( right < left ); } template<class tree> bool operator<=(const tree& left,const tree& right) { return ( !(right < left) ); } template<class tree> bool operator>=(const tree& left,const tree& right) { return ( !(left < right) ); } }//end namespace avl
on line:
rit != mytree.rend() you comparing 2 objects of type:
avltree<char,int>::reverse_iterator which in turn alias for:
std::reverse_iterator<avl_iterator<char, int>::iterator> the c++ standard library defines, in std:: namespace, templated operator != exact match comparing reverse iterators (see paragraph 24.5 of c++11 standard):
template <class iterator1, class iterator2> bool operator!=( const reverse_iterator<iterator1>& x, const reverse_iterator<iterator2>& y) however, have this:
template<class tree> bool operator!=(const tree& left,const tree& right) since template unconstrained (even though template parameter named tree, doesn't mean template accept trees), exact match, templated operator != reverse iterators still more specialized.
therefore, call should not ambiguous. think compiler bug.
to fix issue, make sure inequality operator trees accept trees, anyway idea (you don't want operator compare anything after all):
template<class t> bool operator!=(const avltree<t>& left,const avltree<t>& right)
Comments
Post a Comment