I wrote my own Matrix class with such fields (you can't use STL containers in it)
template <typename T>
class Matrix
{
private:
T *data = nullptr;
size_t rows;
size_t cols;
I also made an iterator for this class:
public:
class Iterator
{
friend Matrix;
private:
T *curr;
public:
Iterator() : curr(nullptr) {}
Iterator(Matrix *matrix) : curr(matrix->data) {}
~Iterator() = default;
......
Iterator begin()
{
Iterator it(this);
std::cout << *it.curr << std::endl;
return it;
}
Iterator end()
{
Iterator it(this);
/*Iterator it(this->data rows * cols);
if (it == nullptr)
{
return it;
}*/
return it;
}
How can I properly write an end() method that would return the next element after the last one? I understand that using address arithmetic you can get the latter, but how can I do it in my code?
CodePudding user response:
I suggest that you let the iterator take a T*
as argument. You can then supply data
to the begin()
iterator and data rows * cols
to the end()
iterator.
Example:
template <class T>
class Matrix {
private:
T* data = nullptr;
size_t rows;
size_t cols;
public:
Matrix(size_t Rows, size_t Cols)
: data{new T[Rows * Cols]}, rows{Rows}, cols{Cols} {}
Matrix(const Matrix&) = delete;
Matrix(Matrix&&) = delete;
~Matrix() { delete[] data; }
class iterator {
private:
T* curr; // store a T*
public:
iterator(T* t) : curr{t} {} // take a T* and store it
iterator& operator () { curr; return *this; }
bool operator==(const iterator& rhs) const { return curr == rhs.curr; }
bool operator!=(const iterator& rhs) const { return !(curr == rhs.curr); }
T& operator*() { return *curr; }
T* operator->() { return curr; }
};
iterator begin() { return {data}; } // begin() takes data
iterator end() { return {data rows * cols}; } // end() takes data rows *cols
};
However, you don't need to implement an iterator yourself for this. You can simply use pointers:
template <class T>
class Matrix {
private:
T* data = nullptr;
size_t rows;
size_t cols;
public:
Matrix(size_t Rows, size_t Cols)
: data{new T[Rows * Cols]}, rows{Rows}, cols{Cols} {}
Matrix(const Matrix&) = delete;
Matrix(Matrix&&) = delete;
~Matrix() { delete[] data; }
using iterator = T*; // iterator is now simply a T*
iterator begin() { return data; }
iterator end() { return data rows * cols; }
};