簡體   English   中英

矢量迭代器不兼容

[英]Vector Iterators Incompatible

我有一個帶有std :: vector數據成員的類,例如

class foo{
public:

const std::vector<int> getVec(){return myVec;} //other stuff omitted

private:
std::vector<int> myVec;

};

現在在我的主要代碼的某些部分,我試圖迭代這樣的向量:

std::vector<int>::const_iterator i = myFoo.getVec().begin();
while( i != myFoo.getVec().end())
{
   //do stuff
   ++i;
}

我到達這個循環的那一刻,我得到了上述錯誤。

你得到這個的原因是,迭代器來自myVec的兩個(或更多)不同的副本。 每次調用myFoo.getVec() ,都會返回向量的副本。 所以迭代器是不兼容的

一些解決方案

返回對std::vector<int>的const引用:

const std::vector<int> & getVec(){return myVec;} //other stuff omitted

另一個解決方案,可能更可取的是獲取向量的本地副本並使用它來獲取迭代器:

const std::vector<int> myCopy = myFoo.getVec();
std::vector<int>::const_iterator i = myCopy.begin();
while(i != myCopy.end())
{
  //do stuff
  ++i;
}

另外+1表示不using namespace std;

您正在返回該向量的副本。 因為您按值返回 - 您對begin()和end()的調用是針對完全不同的向量。 你需要返回一個const&它。

const std::vector<int> &getVec(){return myVec;}

我會這樣做略有不同。 我讓這個課程有點像標准容器

class Data
{
   public:
      typedef std::vector<int>::const_iterator const_iterator;

      const_iterator begin() const { return myVec.begin(); }
      const_iterator end() const { return myVec.end(); }
};

Data::const_iterator i=myFoo.begin();

while(i != myFoo.end())
{
//
}

MSVC STL調試斷言“矢量迭代器不兼容”的另一個原因是在無效的迭代器上運行。

v.erase(i) ,然后比較i != v.end()擦除使i無效,因此它不能用於比較。

好吧,我不認為矢量副本可能是唯一的原因,這對我來說似乎過於苛刻。

在我的情況下,我只是發現損壞的堆棧,堆,無條件的更改也可能導致此失敗,並且實際上隱藏了潛在的原因。 在我的情況下,我改為使用索引器迭代並找到根本原因。

這個斷言可以觸發的另一個原因是你是否將“foo”分配給'malloc'而不是'new',從而有效地跳過了構造函數。

在C ++中從頭開發的項目不太可能發生,但是當將普通C代碼轉換為C ++(用某個stl-vector替換某個結構中的靜態數組[])時,您可能根本沒有意識到所述結構的動態實例(並且其中的成員不會被調用它們的構造函數 - 除非你也將'malloc'改為'new'。

問題是你總是返回另一個向量的副本。 使用參考:

const std::vector<int>& getVec(){return myVec;} //other stuff omitted

您正在創建成員向量的常量副本,而不是訪問成員向量。

改變這個:

const std::vector<int> getVec(){return myVec;} //other stuff omitted

對此:

const std::vector<int> & getVec(){return myVec;} //other stuff omitted

更深入一點,你從這個聲明得到的迭代器:

std::vector<int>::const_iterator i = myFoo.getVec().begin();

是向量的臨時副本的迭代器,它在該語句執行后消失,使迭代器無效。

更改

const std::vector<int> getVec(){return myVec;}

const std::vector<int>& getVec(){return myVec;}

你的getVec()函數返回成員向量的深層副本,因此你要做的兩個getVec()調用來檢索迭代器獲取不同容器的迭代器。 也就是說,您無法從單獨的getVec()。begin()迭代器到達getVec()。end()而不調用未定義的行為。

您可以通過兩種方式解決此問題:

1)讓getVec返回一個const引用(即const std :: vector&)(首選)或......

2)用一個替換兩個getVec()調用,並將結果保存到std :: vector變量。 然后,將該變量用於begin()和end()兩個調用。 例如:

std::vector<int> v = myFoo.getVec();
std::vector<int>::const_iterator b = v.begin();
std::vector<int>::const_iterator e = v.end();

因為您按值返回 - 您對begin()和end()的調用是針對完全不同的向量。 你需要返回一個const&它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM