Пользовательский итератор на основе диапазона для шаблонного вектора векторов

У меня есть задание, которое сводит меня с ума. Я изучал базовые концепции, чтобы расширить свои знания и попытался применить их к этой проблеме, но я немного застрял.

У нас есть файл main.cpp, который тестирует класс VectorOfVectors с таким синтаксисом:

for( int num : intVov )
{
printf( "%d ", num );
}

Мы создаем наш собственный класс VectorOfVectors с шаблонными векторами в качестве элементов.

Мы должны заставить основную функцию работать должным образом, создав собственный настраиваемый итератор, который перебирает все значения, как показано функцией main. Я исследовал основанные на диапазоне итераторы, но меня немного смущает вопрос о том, как создавать свои собственные, и, поскольку это вектор векторов, синтаксис не очень хорошо согласуется с некоторыми онлайн-примерами.

Я хотел бы получить руководство относительно того, как я могу создать этот итератор. Я знаю, что мне нужна функция begin () и end (), а также переопределить функцию operator ++, чтобы заставить ее работать. Будет ли мой итератор использовать значения int в качестве указателей, которые я увеличиваю в operator ++? Нужны ли мне два указателя? Что будут возвращать begin () и end (), итераторы или целые числа, или значения T, или векторы? Как мне построить итератор и какие данные мне нужны для него? Будет ли конструктор итератора принимать два указателя в качестве значений, или один, или как это будет работать? Нужна ли итератору собственная копия VectorOfVectors для итерации (и она будет установлена ​​в конструкторе)?

Как бы я пошел на увеличение указателей? Любая помощь, общие знания или даже советы будут с благодарностью!

Вот то, что я возился, просто как ссылка.

#include <vector>

using std::vector;template< typename T > class VectorOfVectors
{
public:

class iterator
{
public:
//Constructor
iterator(const VectorOfVectors<T> * vov, int pos_vov, int pos_v)
{
_pos_vov = pos_vov;
_pos_v = pos_v;
_vov = vov;
}

bool operator!= (const iterator & other) const
{
return pos != other._pos;
}

int operator* () const;

const iterator operator++ ()
{
_pos_v++;
if (_pos_v == _pos_vov->end())
{
_pos_vov++;
if (_pos_vov == _vov.end())
{
--_pos_vov;
_pos_v = _pos_vov->end();
--_pos_v;
return (*this);
}
else
{
_pos_v = _pos_vov->begin();
return (*this);
}
}
else
{
return (*this);
}
}

private:
int _pos_v;
int _pos_vov;
const VectorOfVectors<T> * _vov;
};

void AddEmptyVector()
{
vectorOfVectors.push_back(new vector<T>());
}

int GetVectorCount() const
{
return vectorOfVectors.size();
}

vector<T> GetVectorAtIndex(int index)
{
return vectorOfVectors.at(index);
}

void AddCopyOfVector(vector<T> & toBeAdded)
{
vectorOfVectors.push_back(toBeAdded);
}

iterator begin() const
{
return iter(this, 0, 0);
}

iterator end() const
{
return iterator(this, 4, 3);
}

private:
vector< vector<T> > vectorOfVectors = new vector< vector<T> >();

};

-1

Решение

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

begin() а также end() должен всегда возвращаться итераторы, не элементы, на которые указывают итераторы (например, не необработанные intв этом случае). В некоторых особых случаях может быть возможно сделать эти необработанные указатели (например, я думаю, что некоторые реализации STL std::vector::iterator сделать это), но, как правило, они должны быть маленькими structСодержит достаточно информации для навигации по родительской структуре данных.

Увидеть эта страница для хорошего описания того, что for (var : collection) синтаксис на самом деле переводится как. Это говорит о том, что вам нужно спроектировать тип итератора Iter который имеет следующие свойства:

  • *Iter возвращает Tили что-то конвертируемое в T (лайк T&). Вы в настоящее время имеете это неправильно — ваш int operator* () const; (который, кажется, не определен?) возвращает intпо какой-то причине.
  • ++Iter перемещает итератор к следующему элементу.
  • Iter1 != Iter2 возвращается false когда два итератора указывают на один и тот же элемент.

Как вы на самом деле создаете Iter Тип полностью зависит от вас. Использование 2-х целочисленных индексов и проверка на «wraparound» на ++ как ты сейчас делаешь мне кажется здоровым.

Другие заметки:

  • Ваш begin() в настоящее время звонки return iter(this, 0, 0);, который даже не скомпилируется.
  • Пожалуйста, не размещайте указатели динамически std::vector, как вы делаете в декларации vectorOfVectors И в AddEmptyVector(), Для начала ни один из них не скомпилируется, потому что для их компиляции вам нужно объявить vectorOfVectors как указатель на вектор указатели на векторы, и вы не хотите этого делать, потому что std::vector внутренне управляет собственным динамическим распределением памяти — избегая необходимости когда-либо вызывать new а также delete является основной причиной, по которой вы используете std::vector на первом месте.
0

Другие решения

Других решений пока нет …