gpt4 book ai didi

c++ - 像迭代器一样编写 STL

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:20:18 24 4
gpt4 key购买 nike

我试图学习像迭代器一样编写 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;
}

当我编译不起作用的部分时,g++ 转储以下错误

ringqueue.cpp: In function ‘int main()’:
ringqueue.cpp:112: error: no match for ‘operator!=’ in ‘it != ring.RingQueue<T, N>::end [with T = int, int N = 10]()’
ringqueue.cpp:48: note: candidates are: bool RingQueue<T, N>::iterator::operator!=(RingQueue<T, N>::iterator&) [with T = int, int N = 10]

工作部分可以无缝编译,在没有工作部分的情况下进行编译。谁能给我解释一下这是怎么回事。

最佳答案

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

    bool operator==(iterator &rhs){
return (this->_container==rhs._container && this->_idx == rhs._idx);
}
bool operator!=(iterator &rhs){
return !(*this==rhs);
}

这里的问题是这些函数接受对其参数的左值引用。这意味着如果您尝试将右值(例如,从函数返回的临时对象)传递给这些运算符,您将收到编译时错误,因为引用无法绑定(bind)到临时对象。要解决此问题,请将参数更改为常量引用:

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

因为 const 引用可以绑定(bind)到临时对象,或者让它们按值获取参数:

    bool operator==(iterator rhs){
return (this->_container==rhs._container && this->_idx == rhs._idx);
}
bool operator!=(iterator rhs){
return !(*this==rhs);
}

无论您做出何种选择,您都应该将这些函数标记为 const,因为它们不会改变接收者对象。

希望这对您有所帮助!

关于c++ - 像迭代器一样编写 STL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10775847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com