C++:遍历向量的向量
Posted
技术标签:
【中文标题】C++:遍历向量的向量【英文标题】:C++: Iterating through a vector of vectors 【发布时间】:2009-11-27 21:18:27 【问题描述】:你好!我正在做这个项目,现在我正在尝试:
-
创建一些对象并将它们存储在向量中,这些向量将存储在另一个向量 V 中
遍历 V 内的向量
遍历各个向量内的对象
无论如何,我只是在网上搜索,然后遇到了 stl for_each 函数。它看起来很整洁,但我遇到了问题。我正在尝试以这种方式使用它:
for_each(V.begin(), V.end(), iterateThroughSmallVectors);
iterateThroug.... 只是对传递给它的向量执行相同操作..
现在我收到一个奇怪的“向量迭代器不兼容”运行时错误。我已经看过了,找不到任何有用的输入..
我不知道它是否有帮助,但 V 是存储在 A 类中的私有向量,它有一个访问器,我试图在 B 类中通过以下方式遍历它:
A->getV().begin(), A->getV().end(), etc..
有人知道发生了什么吗?
编辑:好的,所以我认为最好只发布代码,以及可能出现问题的地方......
gameState.h 中的getTiles:
vector<vector<tile*>> getTiles();
main.cpp 中的 for_each 循环:
for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles);
.
.
void drawTiles(vector<tile*> row)
for_each(row.begin(), row.end(), dTile);
void dTile(tile *t)
t->draw();
创建向量:
int tp = -1;
int bCounter = 0;
int wCounter = 0;
for (int i = 0; i < 8; i++)
vector<tile*> row(8);
for (int j = 0; j < 8; j++)
tile *t = new tile(tp, (i+(SIDELENGTH/2))*SIDELENGTH,
(j+(SIDELENGTH/2))*SIDELENGTH);
row.push_back(t);
tp *= -1;
currState->setTiles(row);
tp *= -1;
以防万一:
void gameState::setTiles(vector<tile*> val)
tiles.push_back(val);
现在更容易发现问题吗?我希望如此......如果你发现我可能在做任何愚蠢的事情,请告诉我,我对 C++ 有点陌生,指针和引用仍然让我感到困惑。
EDIT2:谢谢伙计们,效果很好......对于那个问题,现在看来我在创建瓷砖并将它们放在行矢量中时遇到了问题......似乎即使通过矢量创建并且正确通过,应该在其中的瓷砖不是(它们在 :
for (int j = 0; j < 8; j++)
tile *t = new tile(tp, (i+(SIDELENGTH/2))*SIDELENGTH,
(j+(SIDELENGTH/2))*SIDELENGTH);
row.push_back(t);
tp *= -1;
循环。如果你们中的任何人对解决此问题有任何好的想法,欢迎您帮助我;)同时,我会继续努力解决它
【问题讨论】:
我认为您需要发布准确的代码,并特别标记您遇到此运行时错误的行。 【参考方案1】:A::getV()
的原型是什么?
我只是推测,但如果 A::getV()
没有返回引用,那么它可以解释“向量迭代器不兼容”错误消息。
确实,A->getV().begin()
和 A->getV().end()
将是两个迭代器在不同的向量上:每个 A->getV()
调用返回私有成员的不同副本。
希望这能帮助您调试问题。
编辑:看起来我的预期是正确的:在编辑您提供详细信息的问题后,我可以看到您正在定义
vector<vector<tile*> > getTiles();
因此,在以下声明中:
for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles);
如上所述,对getTiles()
的每次调用都将返回成员向量的单独临时副本。因此,从 begin()
和 end()
返回的迭代器来自不同的向量,因此您在运行时面临的错误消息。
另外,正如Charles in his detailed answer 所指出的,这些临时向量将在到达for_each
的函数体时被销毁。
考虑像这样通过 const 引用返回向量:
const vector<vector<tile*> >& getTiles() const;
您也可以更改drawTiles
以避免更多副本:
void drawTiles(const vector<tile*>& row)
【讨论】:
【参考方案2】:我做的是:直接的方式
vector<vector<int> > vvi;
vector<vector<int> >::iterator vvi_iterator;
vector<int>::iterator vi_iterator;
for(vvi_terator = vvi.begin();vvi_iterator!=vvi.end();++vvi_iterator)
for(vi_iterator = (*vvi_iterator).begin();vi_iterator!=(*vvi_iterator).end();++vi _iterator)
cout<<*vi_iterator<<" ";
这是一个粗略的想法。我发现 for_each 方法对于执行双循环很麻烦。当你想真正对每个元素进行一些计算(比如每个元素的某种映射)时,for_each 很有用
【讨论】:
【参考方案3】:你有几个严重的错误,但首先是一个小错误。
vector<vector<tile*>> getTiles();
在下一个标准出现之前,您需要在 >
之间留一个空格。
vector< vector<tile*> > getTiles();
这个函数按值返回一个vector
,这意味着它会创建一个新的vector
的副本,传递给函数中的return 语句。 (我假设这个函数声明是 curState
的任何类的实例。)
当你这样做时:
for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles);
每次调用 getTiles 都会返回一个单独的临时向量副本。这不仅意味着 begin()
和 end()
的迭代器来自不同的向量,而且在到达 for_each
的函数体时这些向量将被销毁。
看来你需要研究引用并通过引用传递,因为你需要了解这些才能在这些场景中正确使用std::for_each
。
【讨论】:
这基本上是我解释的;) @Gregory Pakosz:在我开始回答这个问题时,您还没有看到使用“真实”代码进行的编辑。也许您想窃取有关临时人员的警告(我认为这是理解的重点)和>>
/> >
来回答您的问题?
@Charles - 当然,就我而言,这只是一种“伟大的思想相似”的有趣感觉。我编辑了答案,以纳入您关于在达到for_each
的正文时被销毁的临时人员的详细信息;以及指向它的链接,以便人们阅读您对>>/> >
的评论。你肯定有我的投票!以上是关于C++:遍历向量的向量的主要内容,如果未能解决你的问题,请参考以下文章