2009-11-27 159 views
1

嘿!我在做这个项目,现在我想:C++:遍历矢量向量

  1. 创建一些对象,并把它们存储在载体,其获取存储在另一个向量V
  2. 迭代通过载体内V
  3. 遍历各个向量中的对象

无论如何,我只是在网上搜索,并且我穿过了stl for_each函数。它看起来很整洁,但我遇到了问题。我想以这种方式来使用它:

for_each(V.begin(), V.end(), iterateThroughSmallVectors); 

的iterateThroug ....只是不传递给它的矢量相同..

现在我得到一个奇怪的“矢量迭代器不兼容“运行时错误。我已经看过它,并找不到任何有用的输入..

我不知道它是否有帮助,但V是一个私人载体<>存储在类A,它有一个访问者,我试图做的B类来遍历它:

A->getV().begin(), A->getV().end(), etc.. 

任何人有什么事情的任何想法?

编辑:好的,所以我认为这是最好只张贴代码,并在问题可能arrising ...

getTiles在gameState.h:

vector<vector<tile*>> getTiles(); 

在主回路的for_each的.cpp:

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++很陌生,指针和引用仍然让我感到困惑。

编辑2:谢谢你,完美的工作......对于这个问题,现在看来我有一个问题,创建的瓷砖和stroing他们在行向量..它似乎即使通过矢量是创造并传递正确的,是被认为是瓷砖在它不是(他们之后失去的:

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; 
    } 

循环如果你们有关于解决这个什么好的想法欢迎您的帮助我;)同时,我会一直试图修复它

+6

我认为你需要发布确切的代码,特别是标记你正在碰到这个运行时错误的行。 – 2009-11-27 21:21:37

回答

7

什么是A::getV()的原型?

我只是在猜测,但如果A::getV()没有返回引用,那么它可以解释“Vector iterators are incompatible”错误消息。

事实上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)

4

我做的是这样的:直接的方式

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非常有用

2

你有几个严重的错误,但首先是一个小问题。

vector<vector<tile*>> getTiles(); 

直到下一个标准出来,你需要>之间的空间。

vector< vector<tile*> > getTiles(); 

这个函数返回一个vector的值,这意味着它产生任何的vector被传递到该函数的返回语句的新副本。 (我认为这个函数的声明是什么类curState是一个实例。)

当你然后做:

for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles); 

到getTiles每次调用将返回一个向量的一个单独的临时副本。这不仅意味着来自begin()end()的迭代器来自差异向量,而且在达到for_each的函数体时,向量将被破坏。

看起来您需要研究参考文献并通过参考,因为您需要在这些场景中正确使用std::for_each之前了解这些参考。

+0

这基本上是我解释的;) – 2009-11-27 22:28:27

+0

@Gregory Pakosz:当我开始这个答案时,你没有看到与'真正'的代码编辑。也许你想窃取关于临时对象的警告(我认为这是一个重要的理解点),用'>>'/'>>'来回答你的答案? – 2009-11-27 22:35:17

+0

@Charles - 当然,从我的角度来看,这只是一个“伟大的思想家一样”的好玩感觉。我编辑了这个答案,以便在你的'for_each'主体达到时临时销毁你的细节。以及链接,以便人们阅读关于'>> />>'的评论。你一定有我的投票! – 2009-11-28 08:43:23