2016-12-16 2 views
2

Я написал следующий код на C++ для итерации по вектору векторов объектов. Я хочу перебирать каждый объект в векторе векторов. Код ниже работает, но у него есть одна особенность, которую я не понимаю.перегрузка ++ в двухслойном итераторе создает странную ошибку

Линия "int types_size = types-> size();" это взлом, используемый в iterator.hpp. Я не очень хорошо знаю язык, поэтому не знаю, нашел ли я ошибку компилятора или это ошибка в моем коде. Переменная «types_size» не требуется. Он используется в двух строках

Первая строка:

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

вторая линия:

if(s<types_size){ 

Если "types_size" заменяется "types-> размер()" в первой строке код будет отключаться при его запуске. Выполнение такой же замены, но только во второй строке, не приводит к ошибке seg. Я не понимаю, что происходит. Любые комментарии к остальной части этого кода будут оценены.

#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

Прочтите свой вопрос немного кратко, но я думаю, что очевидным ответом будет то, что types-> size() возвращает что-то не типа int, а ваша строка «int types_size = types-> size()» принимает другой тип и литье его как int. Например, если у вас двойной а = 3.2; и int b = a; int b будет равно 3. –

+2

Можете ли вы создать [MCVE] –

+0

@LightnessRacesinOrbit, хотя он очень уродлив, это компилируется. – vincent

ответ

1

size() возвращает целое число без знака, так это:

while(s<types->size() 

не ведут себя так же, если s - -1 (его начальное значение). -1 превращается в большое целое число без знака, и сравнение ложно. См. Signed/unsigned comparisons для получения дополнительной информации.

Смежные вопросы