C++ 循环的二维迭代器
我在实现与.end()有关的迭代器类时遇到问题。我遇到的问题是当我尝试在迭代器类中使用for循环时;它当前在2D向量中的最后一个元素之前停止。但是,我希望它在不导致编译器错误的情况下通过最后一个元素,并在print语句中包含最后一个字符 main.cppC++ 循环的二维迭代器,c++,iterator,C++,Iterator,我在实现与.end()有关的迭代器类时遇到问题。我遇到的问题是当我尝试在迭代器类中使用for循环时;它当前在2D向量中的最后一个元素之前停止。但是,我希望它在不导致编译器错误的情况下通过最后一个元素,并在print语句中包含最后一个字符 main.cpp // file contents // aaa // bbb // cce // factory method
// file contents
// aaa
// bbb
// cce
// factory method (adds file contents to 2D <char> vector)
Base *a = Base::create("file");
cout << *a; // overloaded '<<'
现在,当我在迭代器类中使用for循环时,它不包括最后一个字符
for(auto it = a->begin(); it != a->end(); it++)
cout << *it << ' ';
// Note: my iterator class is a nested class inside Base class.
const Base::iterator et = a->begin();
int i = 0;
while(i < 13) {
cout << *et << ' ';
et++;
}
.end打印以下内容
Base::iterator it = aa->end();
cout << *it << '\n';
// prints e
我知道->end()应该指向最后一个字符,但我不知道如何实现它。当我的增量超过运算符++(int)中的最后一个值时,它显示分段错误。目前,我的重载增量方法在最后一个字符处停止,不会超过它。那么,当从for循环打印时,如何实现我的++(int)方法来包含最后一个元素呢?我应该给向量添加一个空元素还是类似的东西
内部Base.cpp
// This function is whats causing the issue. I know it looks ugly.
Base::iterator Base::iterator::operator++(int) {
// base is a Base *, x and y are coordinates for 2D vector
Base::iterator temp(base, x, y); // save value
// if iterator has not reached end
if( !((x == base->vec.size()-1) && (y == base->vec[0].size()-1)) )
{
// if y < row size
if(y < base->vec[0].size()-1)
y++;
// if y has reached end of row, increment x and start y on a new row
else if(x < base->vec.size() && y == base->vec[0].size()-1) {
y=0;
x++;
}
}
return temp;
}
Base::iterator Base::begin() {
return Base::iterator(this, 0, 0);
}
Base::iterator Base::end() {
return Base::iterator(this, vec.size()-1, vec[0].size()-1);
}
//此函数是导致问题的原因。我知道它看起来很丑。
Base::iterator Base::iterator::operator++(int){
//基准是基准*,x和y是二维矢量的坐标
Base::迭代器temp(Base,x,y);//保存值
//如果迭代器尚未到达末尾
如果(!((x==base->vec.size()-1)和&(y==base->vec[0].size()-1)))
{
//如果y<行大小
如果(yvec[0].size()-1)
y++;
//若y已到达行的末尾,则增加x并在新行上开始y
否则,如果(xvec.size()&y==base->vec[0].size()-1){
y=0;
x++;
}
}
返回温度;
}
Base::iterator Base::begin(){
返回Base::iterator(this,0,0);
}
Base::iterator Base::end(){
返回Base::iterator(this,vec.size()-1,vec[0].size()-1);
}
Base.cpp的其余部分
#include "Base.h"
using namespace std;
// Factory method (instantiates 2D vector with file contents)
Base *Base::create(string filename) {/*removed irrelevant code */}
Base::~Base(){}
// prints 2D vector
ostream &operator<<(ostream &os, const Base &val){/*removed irrelevant code*/}
Base::iterator::iterator(Base *b, int m, int n): base(b), x(m), y(n) {}
Base::iterator::~iterator(){}
// returns a character inside 2D vector
char &Base::iterator::operator*() const {
return base->vec[x][y];
}
bool Base::iterator::operator==(const Base::iterator& rhs) const {
return base->vec[x][y] == *rhs;
}
bool Base::iterator::operator!=(const Base::iterator& rhs) const {
return base->vec[x][y] != *rhs;
}
// Bunch of other functions
#包括“Base.h”
使用名称空间std;
//工厂方法(用文件内容实例化二维向量)
Base*Base::create(字符串文件名){/*删除了不相关的代码*/}
Base::~Base(){}
//打印二维向量
ostream&operatorvec[x][y]===*rhs;
}
布尔基::迭代器::运算符=(const Base::iterator&rhs)const{
返回基地->矢量[x][y]!=*rhs;
}
//一系列其他函数
任何帮助都将不胜感激。Base::iterator(this,vec.size()-1,vec[0].size()-1)代码>这将返回有效的最后一个元素。所以您需要将其更改为Base::iterator(这是vec.size(),0)代码>,并更新条件以切换到循环中的新行
比如:
// if iterator has not reached end
if(x < base->vec.size())
{
++y;
// if y has reached end of row, increment x and start y on a new row
if(y >= base->vec[0].size() {
y=0;
++x;
}
}
如果你要包装一个2D向量,在底层实现中使用1D向量可能更好。是的,我考虑过了,但这需要完全重做我所有的方法来使用1D向量,并添加额外的类变量。最坏的情况是,我最终可能会这么做。只是想看看2D迭代器是否有任何解决方案。如何解决分段错误?return Base::iterator(this,vec.size(),vec[0].size());显示分段错误。(3,3)是不允许的。2D向量只有索引(0,0)->(2,2)。Oops,坏界,x// This function is whats causing the issue. I know it looks ugly.
Base::iterator Base::iterator::operator++(int) {
// base is a Base *, x and y are coordinates for 2D vector
Base::iterator temp(base, x, y); // save value
// if iterator has not reached end
if( !((x == base->vec.size()-1) && (y == base->vec[0].size()-1)) )
{
// if y < row size
if(y < base->vec[0].size()-1)
y++;
// if y has reached end of row, increment x and start y on a new row
else if(x < base->vec.size() && y == base->vec[0].size()-1) {
y=0;
x++;
}
}
return temp;
}
Base::iterator Base::begin() {
return Base::iterator(this, 0, 0);
}
Base::iterator Base::end() {
return Base::iterator(this, vec.size()-1, vec[0].size()-1);
}
#include "Base.h"
using namespace std;
// Factory method (instantiates 2D vector with file contents)
Base *Base::create(string filename) {/*removed irrelevant code */}
Base::~Base(){}
// prints 2D vector
ostream &operator<<(ostream &os, const Base &val){/*removed irrelevant code*/}
Base::iterator::iterator(Base *b, int m, int n): base(b), x(m), y(n) {}
Base::iterator::~iterator(){}
// returns a character inside 2D vector
char &Base::iterator::operator*() const {
return base->vec[x][y];
}
bool Base::iterator::operator==(const Base::iterator& rhs) const {
return base->vec[x][y] == *rhs;
}
bool Base::iterator::operator!=(const Base::iterator& rhs) const {
return base->vec[x][y] != *rhs;
}
// Bunch of other functions
// if iterator has not reached end
if(x < base->vec.size())
{
++y;
// if y has reached end of row, increment x and start y on a new row
if(y >= base->vec[0].size() {
y=0;
++x;
}
}
bool Base::iterator::operator==(const Base::iterator& rhs) const {
return base == rhs.base && x == rhs.x && y == ris.y;
}
bool Base::iterator::operator!=(const Base::iterator& rhs) const {
return !(base == rhs.base && x == rhs.x && y == ris.y);
}