S G*_*nck 5 c++ iterator operator-overloading std reverse-iterator
我正在研究一个实现自己的迭代器的容器,我正在使用它与std :: reverse_iterator <>来获得反向迭代功能.我可以将反向迭代器分配给rend或rbegin,但是当我尝试访问它的任何功能(例如!=或==)时,我得到:
1 IntelliSense: more than one 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>>>>>
Run Code Online (Sandbox Code Playgroud)
我的迭代器运算符重载:
bool operator == ( const avl_iterator& rhs ) const { return ( _node == rhs._node); }
bool operator != ( const avl_iterator& rhs ) const { return ( _node != rhs._node); }
Run Code Online (Sandbox Code Playgroud)
和我的反向迭代器的实现
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;
Run Code Online (Sandbox Code Playgroud)
和迭代器typedef:
typedef typename tree::node node;
typedef typename tree::node_ptr node_ptr;
typedef typename tree::value_type* pointer;// for 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;
Run Code Online (Sandbox Code Playgroud)
我是如何使用运营商的
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 this line
{
}
Run Code Online (Sandbox Code Playgroud)
和iterator类(const_iterator是相同的东西,但有一个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;// for 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;
}
};
Run Code Online (Sandbox Code Playgroud)
和树类:
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 and 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
Run Code Online (Sandbox Code Playgroud)
在这行上:
rit != myTree.rend()
Run Code Online (Sandbox Code Playgroud)
您正在比较两个类型的对象:
avltree<char,int>::reverse_iterator
Run Code Online (Sandbox Code Playgroud)
这又是以下项的别名:
std::reverse_iterator<avl_iterator<char, int>::iterator>
Run Code Online (Sandbox Code Playgroud)
C ++标准库在std::名称空间中定义了一个模板,该模板operator !=与比较反向迭代器完全匹配(请参阅C ++ 11标准的24.5段):
template <class Iterator1, class Iterator2>
bool operator!=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y)
Run Code Online (Sandbox Code Playgroud)
但是,您也有以下内容:
template<class tree> bool operator!=(const tree& left,const tree& right)
Run Code Online (Sandbox Code Playgroud)
由于模板是不受约束的(即使template参数名为tree,但这并不意味着模板将仅接受树),因此这也是完全匹配的,但是operator !=用于反向迭代器的模板仍然更加专业。
因此,调用应该不会有歧义。我认为这是一个编译器错误。
要解决此问题,请确保您的树木不等式运算符仅接受树木,这绝对是个好主意(您确实不希望运算符进行任何比较):
template<class T> bool operator!=(const avltree<T>& left,const avltree<T>& right)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1666 次 |
| 最近记录: |