C++ 编写类似STL的迭代器

C++ 编写类似STL的迭代器,c++,data-structures,stl,iterator,operators,C++,Data Structures,Stl,Iterator,Operators,我试图学习编写类似stl的迭代器,为此我编写了一个简单的循环数组,并在其中添加了一个迭代器。请查看代码底部以查看问题 template<typename T, int N> class RingQueue{ T * _marray; int _mbegin; int _msize; public: RingQueue(){ _marray = new T[N]; _mbegin = 0; _msize=

我试图学习编写类似stl的迭代器,为此我编写了一个简单的循环数组,并在其中添加了一个迭代器。请查看代码底部以查看问题

template<typename T, int N>
class RingQueue{
    T * _marray;
    int _mbegin;
    int _msize;
public:
    RingQueue(){
        _marray = new T[N];
        _mbegin = 0;
        _msize= 0;
    }   
    void push_back(const T& val){
        if(_msize!=N){
            _marray[(_mbegin+_msize)%N] = val;
            _msize++;
        }
        else
            throw "Queue Full";
    }   
    T pop_front(){
        if(_msize!=0){
            T&val = _marray[_mbegin];
            _mbegin = (_mbegin+1)%N;
            _msize--;
            return val;
        }
        else
            throw "Queue Empty";
    }

    class iterator{
        RingQueue<T,N>* _container;
        int _idx;
        public:
        iterator(RingQueue<T,N>* container,int idx):_container(container){
            _idx = idx;
        }

        bool operator==(iterator &rhs){
            return (this->_container==rhs._container && this->_idx == rhs._idx);
        }
        bool operator!=(iterator &rhs){
            return !(*this==rhs);
        }   
        T operator*(){
            if(_container->_msize>0&&_idx<_container->_msize){
                return _container->_marray[(_container->_mbegin+_idx)%N];
            }
        }

        iterator& operator++(){
            if(_container->_msize ==0){
                *this = _container->end();
                return *this;
            }
            if(_idx==_container->_msize){   
                *this = _container->end();
                return *this;
            }
            _idx++;
            return *this;
        }
    };
    iterator begin(){
        return iterator(this,0);
    }
    iterator end(){
        return iterator(this,_msize);
    }
};
int current=0;
int gen(){
    return current++;
}

int curr_op=0;
int operation(){
    return 2*(curr_op++&1)-1;
}
int main(){
    RingQueue<int,10> ring;
    vector<int> v(9),op(9);
    generate(v.begin(),v.end(),gen);
    random_shuffle(v.begin(),v.end());
    copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));    
    cout<<endl;

    generate(op.begin(),op.end(),operation);        
    random_shuffle(op.begin(),op.end());
    // copy(op.begin(),op.end(),ostream_iterator<int>(cout," "));   
    cout<<endl;

    for(vector<int>::iterator itv  = v.begin();itv!=v.end();itv++){
        try{
            ring.push_back(*itv);   
        }catch(const char * e){
            cout<<*itv<<e<<endl;
        }
    }
    //works
    RingQueue<int,10>::iterator ite = ring.end();
    for(RingQueue<int,10>::iterator it = ring.begin(); it!=ite; ++it){
        cout<<*it<<endl;
    }
    // doesn't work 
    for(RingQueue<int,10>::iterator it = ring.begin(); it!=ring.end(); ++it){
        cout<<*it<<endl;
    }
    return 0;
}
模板
类环形队列{
T*_marray;
国际姆贝金;
int _msize;
公众:
环形队列(){
_marray=新T[N];
_姆贝金=0;
_msize=0;
}   
无效推回(常数T&val){
如果(msize!=N){
_marray[(_mbegin+_msize)%N]=val;
_msize++;
}
其他的
抛出“队列已满”;
}   
T pop_front(){
如果(msize!=0){
T&val=_marray[_mbegin];
_姆贝金=(_姆贝金+1)%N;
_msize--;
返回val;
}
其他的
抛出“队列空”;
}
类迭代器{
环形队列*\u容器;
int_idx;
公众:
迭代器(RingQueue*容器,intIDX):\u容器(容器){
_idx=idx;
}
布尔运算符==(迭代器和rhs){
返回(this->_container==rhs._container&&this->_idx==rhs.\u idx);
}
布尔运算符!=(迭代器和rhs){
返回!(*此==rhs);
}   
T算子*(){
if(_container->msize>0&&u idxmsize){
返回_container->_marray[(_container->_mbegin+_idx)%N];
}
}
迭代器和运算符++(){
如果(_container->_msize==0){
*this=_container->end();
归还*这个;
}
如果(_idx==_container->_msize){
*this=_container->end();
归还*这个;
}
_idx++;
归还*这个;
}
};
迭代器begin(){
返回迭代器(this,0);
}
迭代器结束(){
返回迭代器(这个,msize);
}
};
int电流=0;
int gen(){
返回电流++;
}
int curr_op=0;
int操作(){
返回2*(curr_op++&1)-1;
}
int main(){
环队列环;
向量v(9),op(9);
生成(v.begin(),v.end(),gen);
随机洗牌(v.begin(),v.end());
复制(v.begin(),v.end(),ostream_迭代器(cout,“”);

我认为问题在于这些方面:

    bool operator==(iterator &rhs){
        return (this->_container==rhs._container && this->_idx == rhs._idx);
    }
    bool operator!=(iterator &rhs){
        return !(*this==rhs);
    }  
这里的问题是这些函数接受对其参数的左值引用。这意味着如果您尝试传递右值(例如,从函数返回的临时对象)在这些运算符中,将出现编译时错误,因为引用无法绑定到临时对象。若要解决此问题,请将参数更改为常量引用:

    bool operator==(const iterator &rhs){
        return (this->_container==rhs._container && this->_idx == rhs._idx);
    }
    bool operator!=(const iterator &rhs){
        return !(*this==rhs);
    }  
由于常量引用可以绑定到临时变量,或者让临时变量按值获取其参数:

    bool operator==(iterator rhs){
        return (this->_container==rhs._container && this->_idx == rhs._idx);
    }
    bool operator!=(iterator rhs){
        return !(*this==rhs);
    }  
无论您做出何种选择,您都应该标记这些函数
const
,因为它们不会改变接收方对象

希望这有帮助!

#包括
#include <vector>
#include <iostream>
#include <sstream>
#include <iterator>
using namespace std;

template<typename T, int N>
class RingQueue{
    T * _marray;
    int _mbegin;
    int _msize;
public:
    RingQueue(){
        _marray = new T[N];
        _mbegin = 0;
        _msize= 0;
    }   
    void push_back(const T& val){
        if(_msize!=N){
            _marray[(_mbegin+_msize)%N] = val;
            _msize++;
        }
        else
            throw "Queue Full";
    }   
    T pop_front(){
        if(_msize!=0){
            T&val = _marray[_mbegin];
            _mbegin = (_mbegin+1)%N;
            _msize--;
            return val;
        }
        else
            throw "Queue Empty";
    }

    class iterator{
        RingQueue<T,N>* _container;
        int _idx;
        public:
        iterator(RingQueue<T,N>* container,int idx):_container(container){
            _idx = idx;
        }

        bool operator==(iterator rhs){ // XXX do not pass it as a reference
            return (this->_container==rhs._container && this->_idx == rhs._idx);
        }
        bool operator!=(iterator rhs){ // XXX do not pass it as a reference
            return !(*this==rhs);
        }   
        T operator*(){
            if(_container->_msize>0&&_idx<_container->_msize){
                return _container->_marray[(_container->_mbegin+_idx)%N];
            }
            throw "XXX"; // XXX missing return statement
        }

        iterator& operator++(){
            if(_container->_msize ==0){
                *this = _container->end();
                return *this;
            }
            if(_idx==_container->_msize){   
                *this = _container->end();
                return *this;
            }
            _idx++;
            return *this;
        }
    };
    iterator begin(){
        return iterator(this,0);
    }
    iterator end(){
        return iterator(this,_msize);
    }
};
int current=0;
int gen(){
    return current++;
}

int curr_op=0;
int operation(){
    return 2*(curr_op++&1)-1;
}
int main(){
    RingQueue<int,10> ring;
    vector<int> v(9),op(9);
    generate(v.begin(),v.end(),gen);
    random_shuffle(v.begin(),v.end());
    copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));    
    cout<<endl;

    generate(op.begin(),op.end(),operation);        
    random_shuffle(op.begin(),op.end());
    // copy(op.begin(),op.end(),ostream_iterator<int>(cout," "));   
    cout<<endl;

    for(vector<int>::iterator itv  = v.begin();itv!=v.end();itv++){
        try{
            ring.push_back(*itv);   
        }catch(const char * e){
            cout<<*itv<<e<<endl;
        }
    }
    for(RingQueue<int,10>::iterator it = ring.begin(); it!=ring.end(); ++it){
        cout<<*it<<endl;
    }
    return 0;
}
#包括 #包括 #包括 使用名称空间std; 模板 类环形队列{ T*_marray; 国际姆贝金; int _msize; 公众: 环形队列(){ _marray=新T[N]; _姆贝金=0; _msize=0; } 无效推回(常数T&val){ 如果(msize!=N){ _marray[(_mbegin+_msize)%N]=val; _msize++; } 其他的 抛出“队列已满”; } T pop_front(){ 如果(msize!=0){ T&val=_marray[_mbegin]; _姆贝金=(_姆贝金+1)%N; _msize--; 返回val; } 其他的 抛出“队列空”; } 类迭代器{ 环形队列*\u容器; int_idx; 公众: 迭代器(RingQueue*容器,intIDX):\u容器(容器){ _idx=idx; } 布尔运算符==(迭代器rhs){//XXX不将其作为引用传递 返回(this->_container==rhs._container&&this->_idx==rhs.\u idx); } 布尔运算符!=(迭代器rhs){//XXX不将其作为引用传递 返回!(*此==rhs); } T算子*(){ if(_container->msize>0&&u idxmsize){ 返回_container->_marray[(_container->_mbegin+_idx)%N]; } 抛出“XXX”;//XXX缺少返回语句 } 迭代器和运算符++(){ 如果(_container->_msize==0){ *this=_container->end(); 归还*这个; } 如果(_idx==_container->_msize){ *this=_container->end(); 归还*这个; } _idx++; 归还*这个; } }; 迭代器begin(){ 返回迭代器(this,0); } 迭代器结束(){ 返回迭代器(这个,msize); } }; int电流=0; int gen(){ 返回电流++; } int curr_op=0; int操作(){ 返回2*(curr_op++&1)-1; } int main(){ 环队列环; 向量v(9),op(9); 生成(v.begin(),v.end(),gen); 随机洗牌(v.begin(),v.end()); 复制(v.begin(),v.end(),ostream_迭代器(cout,“”);
cout为自定义容器编写迭代器时,您可能会发现使用它很有帮助。它是一个库,允许您仅定义迭代器的基本操作(递增、取消引用和相等比较,以及,如果适用,递减和前进)并通过提供所有必需的运算符来填补空白。下面是使用boost::iterator_facade时迭代器的外观:

class iterator : public boost::iterator_facade<iterator, T, boost::forward_traversal_tag>{
    RingQueue<T,N>* _container;
    int _idx;
public:
    iterator(RingQueue<T,N>* container,int idx):_container(container){
        _idx = idx;
    }

    bool equal(const iterator &rhs) const {
        return (this->_container==rhs._container && this->_idx == rhs._idx);
    }

    T dereference() const {
        if(_container->_msize>0&&_idx<_container->_msize){
            return _container->_marray[(_container->_mbegin+_idx)%N];
        }
    }

    void increment(){
        if(_container->_msize ==0)
            *this = _container->end();
        else if(_idx==_container->_msize)
            *this = _container->end();
        else
            _idx++;
    }
};
类迭代器:公共boost::迭代器{ 环形队列*\u容器; int_idx; 公众: 迭代器(RingQueue*容器,intIDX):\u容器(容器){ _idx=idx; } 布尔相等(常量迭代器和rhs)常量{ 返回(this->_container==rhs._container&&this->_idx==rhs.\u idx); } T取消引用()常量{ if(_container->msize>0&&u idxmsize){ 返回_container->_marray[(_container->_mbegin+_idx)%N]; } } 无效增量(){ 如果(_container->_msize==0) *this=\u容器->结束()
class iterator : public boost::iterator_facade<iterator, T, boost::forward_traversal_tag>{
    RingQueue<T,N>* _container;
    int _idx;
public:
    iterator(RingQueue<T,N>* container,int idx):_container(container){
        _idx = idx;
    }

    bool equal(const iterator &rhs) const {
        return (this->_container==rhs._container && this->_idx == rhs._idx);
    }

    T dereference() const {
        if(_container->_msize>0&&_idx<_container->_msize){
            return _container->_marray[(_container->_mbegin+_idx)%N];
        }
    }

    void increment(){
        if(_container->_msize ==0)
            *this = _container->end();
        else if(_idx==_container->_msize)
            *this = _container->end();
        else
            _idx++;
    }
};