как мне получить доступ (например, cout) к текущему значению итераторов в многомерных векторах STL (C )

#c #stl #vector

#c #stl #вектор

Вопрос:

Я все еще новичок в использовании STL. Следующий фрагмент кода заполняет 3D-вектор (Ы) и отлично компилируется (g ).

 const int maxBonds = 6;
vector< vector< vector<int> > > S;
S.resize(maxBonds);
populate(S); // function that returns S with various layers filled with int data in rows and columns.
for (vector<vector<vector<int> > >::iterator Slayer = S.begin(); Slayer != S.end(); Slayer  ) {
    cout << "Layer contains " << Slayer->size() << " rows" << endl;
    for (vector<vector<int> >::iterator Srow = Slayer->begin(); Srow != Slayer->end(); Srow  ) {
        for (vector<int>::iterator Scol = Srow->begin(); Scol != Srow->end(); Scol  ) {
            cout << *Scol;
        }
        cout << endl;
    }
    cout << endl;
}
  

Это выполняется нормально:

 Layer contains 0 rows

Layer contains 5 rows
000
200
020
220
002

Layer contains 12 rows
100
010
210
... // etc.
  

Однако я хотел бы распечатать значение внешних итераторов (Slayer, Srow) во время итерации. Как мне правильно разыменовать текущее значение Slayer, т.Е.

  cout << "Layer # " << Slayer->??? << " contains " << Slayer->size() << " rows" << endl;
  

Комментарии:

1. разве Slayer не является итератором? Разве * Slayer не работает просто?

2. @Umut — работает, но это был бы вектор, и вы не можете распечатать вектор просто так.

3. @Kiril, действительно, это вектор<vector<int> >

4. @Rolf, вы могли бы сформулировать проблему лучшим образом для дальнейшего использования, возможно, формулировка 3D-объекта с указателем на vector<вектор<int> > уменьшает уровень вложений, что-то вроде этого…

5. @Umut: попытка выполнить cout << *Slayer не работает, оператор << здесь нельзя использовать.

Ответ №1:

Если вам нужен текущий векторный «индекс», я думаю, что стандартный способ сделать это — увеличить другое значение.

 unsigned int countSlayer = 0;

for (vector<vector<vector<int> > >::iterator Slayer = S.begin(); Slayer != S.end(); Slayer  ,   countSlayer) {

    cout << "Layer # " << countSlayer << " contains " << Slayer->size() << " rows" << endl;

    for (vector<vector<int> >::iterator Srow = Slayer->begin(); Srow != Slayer->end(); Srow  ) {
        for (vector<int>::iterator Scol = Srow->begin(); Scol != Srow->end(); Scol  ) {
            cout << *Scol;
        }
        cout << endl;
    }
    cout << endl;
}
  

Вы также можете попытаться вычесть begin() из итератора, но это плохо работает со всеми типами итераторов (у меня не хватает времени на выполнение некоторых тестов).

Ответ №2:

Таким образом, *Scol вы получаете значение int в последнем векторе, *Srow вы получаете вектор строки, *Slayer вы получаете вектор слоев, содержащих вектор строк.

Ответ №3:

Вы не можете сделать это напрямую.

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


Что-то вроде:

 void Print2dIntVector( const vector<vector<int> >amp; v )
{
    // ..
}
void Print3dIntVector( const vector< vector< vector<int> > >amp; v )
{
    // ..
}
  

Совет — используйте typedef вместо записи всех этих длинных вложенных векторов.

РЕДАКТИРОВАТЬ: Конечно, вы всегда можете перегрузить operator<< для этих типов (векторов)