У меня есть задание, которое сводит меня с ума. Я изучал базовые концепции, чтобы расширить свои знания и попытался применить их к этой проблеме, но я немного застрял.
У нас есть файл 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> >();
};
От 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
на первом месте.Других решений пока нет …