C++ 编写类似STL的迭代器
我试图学习编写类似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=
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++;
}
};