«ошибка: назначение места только для чтения» в unordered_map (C ++) - PullRequest
1 голос
/ 19 ноября 2009

У меня есть неудобная хеш-таблица (в частности, unordered_map) с int ключами и vector< vector< int >> данными. Мне периодически нужно обновлять элементы в этом двумерном векторе. Нет внутренней причины, по которой я не смог бы этого сделать, верно? Более новый компилятор g ++, на который я переключился, жалуется на назначение места только для чтения в строке, обозначенной ниже.

typedef std::tr1::unordered_map< int, vector< vector< int > > > pimap;

vector< Strain * > liveStrains;
pimap phenotypeIs;
int NUM_DEMES = 3;

...
vector< Strain * >::const_iterator lsItr;
for ( lsItr = liveStrains.begin(); lsItr != liveStrains.end(); ++lsItr ) {
 int thisP = (*lsItr)->getPhenotype();
 pimap::iterator piItr = phenotypeIs.begin();
 piItr = phenotypeIs.find( thisP );
 if ( piItr != phenotypeIs.end() ) {
   for ( int d = 0; d < NUM_DEMES; d++ ) {
      ( piItr -> second )[ thisStep ].at( d ) = (*lsItr)->getI( d );  // error here
   }
 }
}

Я новичок в C ++, так что нет ничего слишком очевидного. Спасибо за любую помощь.


По предложению Тима

Я заменил соответствующие части кода выше следующим:

  pimap::iterator piItr = phenotypeIs.find( thisP );
  if ( piItr != phenotypeIs.end() ) {
    for ( int d = 0; d < NUM_DEMES; d++ ) {
      vector< vector< int > > & thisVec2 = piItr->second;
      vector<int> & thisVec = thisVec2.at( thisStep );
      int & ii = thisVec.at( d );
      ii = (*lsItr)->getI( d );
      // ( piItr -> second )[ thisStep ].at( d ) = (*lsItr)->getI( d ); // error was here
    }

Этот код компилируется без ошибки и, кажется, работает нормально. Как и Тим, я все еще не совсем понимаю, почему исправление работает. Ранее эта ошибка появлялась в gcc версии 4.1.2 20080704 (Red Hat 4.1.2-44), но не в gcc версии 4.0.1 (Apple Inc., сборка 5465). Я постараюсь более аккуратно разобрать ошибку, когда у меня нет жестких сроков!

Ответы [ 2 ]

1 голос
/ 19 ноября 2009

Вы уверены, что действительно есть thisStep + 1 элементы в каждом векторе первого уровня и NUM_DEMES элементы в каждом векторе второго уровня?

Вы на самом деле не назначаете итератору карты, если я правильно прочитал, поэтому я подозреваю, что ошибка в векторном доступе.

Может быть полезно разбить это последнее утверждение на несколько утверждений, чтобы в каждом из них было сделано только одно, чтобы сузить суть проблемы. например,

Strain* strain = *lsItr;
vector<vector<int> >& vv = piItr->second;
vector<int>& v = vv[thisStep];
int& i = v.at(d);     // <-- My bet is that the error occurs here or the prev. line
i = strain->getI( d );

Кстати, piItr = phenotypeIs.begin(); здесь не имеет никакого эффекта, это может быть просто:

pimap::iterator piItr = phenotypeIs.find( thisP );
0 голосов
/ 19 ноября 2009
( piItr -> second )[ thisStep ].at( d )

at () возвращает итератор во внутренний вектор, а не доступ к значению. То, что вы хотите, это

 *(( piItr -> second )[ thisStep ].at( d ))
...