Search code examples
c++iteratorsparse-matrix

Method to check if something has been changed through the iterator


I have made a List of Lists implementation of a sparse matrix, and I've implemented iterator and const_iterator with success.

The iterator doesn't point directly to the container where the value is stored, but creates a struct, named element, so defined:

template <typename T>
struct element{
 int i,j; //Coordinates
 T value;
};

But there's one problem with the iterator: when I use it to edit the values in the struct, this should even affect the internal structure of the matrix. I thought to store the original values in other private attributes of the iterator, then to compare them with the data stored into the struct: if something is different I'd call the methods of the matrix to edit the real internal structure.

The only thing I miss is: when is it the right moment to call this method inside iterator class?


Solution

  • The short answer, you should call this function as soon as *it is assigned to, where it is an iterator.

    I don't think you have the right approach. Iterators in C++ can't really cache changes, because there might be other iterators pointing at the same place in the container. Changes made via the iterator should affect the matrix immediately, and changes in the matrix should be visible via the iterator immediately. Here's a test case:

    typedef whatever_type_you_like T; // maybe int
    
    matrix<T> mymatrix(5, 5);
    matrix<T>::iterator it1 = get_iterator_from(mymatrix, 2, 3);
    matrix<T>::iterator it2 = get_iterator_from(mymatrix, 2, 3);
    assert(it1 == it2);
    assert(*it1 == *it2);
    assert(*it1 == T());
    
    *it1 = T(1); // or some other constructor parameter
    assert(*it1 != T());
    assert(*it1 == T(1));
    assert(*it2 == T(1));
    assert(it1 == it2);
    assert(*it1 == *it2);
    assert(*it1 == mymatrix[2][3]); // or whatever syntax you have for matrix access
    
    *it2 = T(2);
    assert(*it1 != T(1));
    assert(*it1 == T(2));
    assert(*it2 == T(2));
    assert(it1 == it2);
    assert(*it1 == *it2);
    assert(*it2 == mymatrix[2][3]);
    
    mymatrix[2][3] = T(3);
    assert(*it2 != T(2));
    assert(*it2 == mymatrix[2][3]);
    

    So rather than element storing a copy of the value intended for the matrix, it should directly access the matrix, reading the value from there and storing the value there (and hence creating a real entry in the sparse matrix when required to store). Also, your element class should be convertible to T.