Home > Enterprise >  Iterator for Matrix Native class class
Iterator for Matrix Native class class

Time:05-24

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
};

Demo


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; }
};
  •  Tags:  
  • c
  • Related