2016-12-16 3 views
2

以下のC++コードを記述して、オブジェクトのベクトルのベクトルを反復処理しました。ベクトルのベクトルのすべてのオブジェクトを繰り返し処理したいと思います。以下のコードは動作しますが、私には分かりません。2層イテレータで++をオーバーロードすると奇妙なバグが発生する

「int types_size = types-> size();」という行は、 iterator.hppで採用されているハックです。私は本当に言語をよく知らないので、コンパイラのバグが見つかったのか、これが私のコードのバグであるのか分かりません。変数 "types_size"は必要ありません。 "types_size" 第1行目の "各種タイプ - >サイズ()" に置き換えられる場合

if(s<types_size){ 

while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&(((*types)[s])->end()))){ 

二行目:これは、二列に

最初の行に使用されコードが実行されると、seg faultが発生します。 2番目の行だけで同じ置換えを行っても、seg faultは発生しません。私は何が起こっているのか分からない。このコードの残りの部分についてのコメントは高く評価されます。

#ifndef _iterator_hpp_ 
#define _iterator_hpp_ 

#include <vector> 
using namespace std; 

typedef double Object; 

typedef vector<Object> ObjectVector; 

class Region{ 
public: 
    vector<ObjectVector*> types; 
}; 

class ObjectIterator{ 
private: 
    int s; 
    vector<ObjectVector*> *types; 
protected: 

public: 
    Object *object; 
    bool finished; 

    ObjectIterator operator++(){ 
     if (s>=0) object++; // increments to next object 
     int types_size=types->size(); // this is a hack that fixes a seg fault (compiler bug??) 
     // *types is a vector<ObjectVector*>. (*types)[s] is the "sth" ObjectVector*. 
     // &(*iterator) gives a pointer to the object pointed to by iterator. 
     //((*types)[s])->end()) is an iterator that points past the end of 
     // the ObjectVector* ((*types)[s])->end()) 
     while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&(*  ((*types)[s])->end()))){ 
      //need to increment to next non-empty types 
      s++; 
      if(s<types_size){ 
       object=&((*(*types)[s])[0]); 
      }else{finished=true;} 
     } 
     return (*this); 
    } 

    /*---------------------constructor-------------------------------------------------------- 

     start with s=-1 and increment to first object */ 

    ObjectIterator(vector<ObjectVector*> *typesarg):finished(false) { 
     types=typesarg;s=-1;++(*this); 
    }; 

}; 

#endif 

--------------------------------メイン---------- ----------------------

// it.cpp 

// g++ it.pp 

#include <iostream> 

#include <vector> 

#include "iterator.hpp" 

using namespace std; 

int num_types=3; 

int main(){ 

    Region region; 

    int num_objects[num_types]; 

    num_objects[0]=1; 
    num_objects[1]=3; 
    num_objects[2]=5; 

    // create an ObjectList for each type 


    for(int s=0;s<num_types;s++){ 
    ObjectVector *objectlist = new ObjectVector; 

    for(int i=0;i<num_objects[s];i++){ 
     objectlist->push_back((double)2*(i+1)*(s+1)); 
    } 
    region.types.push_back(objectlist); 
    } 

    cout <<"types.size="<< region.types.size()<<endl; 

    for(ObjectIterator OI(&region.types); !OI.finished ; ++OI) 
    { 
     cout <<*(OI.object)<<endl; 
    } 


} 
+0

あなたの質問をちょっと読んでください。しかし、私は明らかな答えは型 - > size()が型intではなく、あなたの行 "int types_size = types-> size()"が他の型に変換し、intとしてキャストします。 たとえば、double a = 3.2の場合、 int b = a; int bは3に等しくなります。 –

+2

非常に醜いですが、[MCVE] –

+0

@ LightnessRacesinOrbitを生成できますか?これはコンパイルできます。 – vincent

答えて

1

size()このように、符号なし整数を返します場合

while(s<types->size() 

は同じように動作しません。 sは-1(初期値)です。 -1は大きな符号なし整数に変換され、比較はfalseです。詳細については、Signed/unsigned comparisonsを参照してください。

関連する問題