Clean ways to write multiple ‘for’ loops

The first thing is that you don’t use such a data structure. If
you need a three dimensional matrix, you define one:

class Matrix3D
{
    int x;
    int y;
    int z;
    std::vector<int> myData;
public:
    //  ...
    int& operator()( int i, int j, int k )
    {
        return myData[ ((i * y) + j) * z + k ];
    }
};

Or if you want to index using [][][], you need an operator[]
which returns a proxy.

Once you’ve done this, if you find that you constantly have to
iterate as you’ve presented, you expose an iterator which will
support it:

class Matrix3D
{
    //  as above...
    typedef std::vector<int>::iterator iterator;
    iterator begin() { return myData.begin(); }
    iterator end()   { return myData.end();   }
};

Then you just write:

for ( Matrix3D::iterator iter = m.begin(); iter != m.end(); ++ iter ) {
    //  ...
}

(or just:

for ( auto& elem: m ) {
}

if you have C++11.)

And if you need the three indexes during such iterations, it’s
possible to create an iterator which exposes them:

class Matrix3D
{
    //  ...
    class iterator : private std::vector<int>::iterator
    {
        Matrix3D const* owner;
    public:
        iterator( Matrix3D const* owner,
                  std::vector<int>::iterator iter )
            : std::vector<int>::iterator( iter )
            , owner( owner )
        {
        }
        using std::vector<int>::iterator::operator++;
        //  and so on for all of the iterator operations...
        int i() const
        {
            ((*this) -  owner->myData.begin()) / (owner->y * owner->z);
        }
        //  ...
    };
};

Leave a Comment