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

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -