two dimensional iterators

A

Alexander Stippler

Hi,

I have to design some two dimensional iterators and I'm not quite sure about
the design. I'd like to have the iterators mostly STL-like. The STL does
not contain two dimensional iterators, I think. I'm not sure, what is the
best way of design and usage syntax.
Is there a good reference or example online? How could such an iterator look
like for the equivalent of std::vector, lets say my::matrix to "exploit"
the pointers as iterators like std::vector does?

regards,
alex
 
V

Victor Bazarov

Alexander Stippler said:
I have to design some two dimensional iterators and I'm not quite sure about
the design. I'd like to have the iterators mostly STL-like. The STL does
not contain two dimensional iterators, I think. I'm not sure, what is the
best way of design and usage syntax.

The same as with all other iterators, I suppose.
Is there a good reference or example online? How could such an iterator look
like for the equivalent of std::vector, lets say my::matrix to "exploit"
the pointers as iterators like std::vector does?

Do you mean that your iterator when dereferenced will return another
iterator? That's the essence of two-dimensionality, as I understand
it. So, what's the big deal?

template<class T> class Iterator
{
...
T& operator*();
};

template<class T> class SuperIterator
{
...
Iterator<T>& operator*();
};

Fill in the '...' with all the usual stuff. Also, make your 'my::matrix'
return a SuperIterator<T> from 'begin' and 'end' member functions. OTOH,
if you implement your iterator as a template, then just make 'my::matrix'
return iterator<iterator<T> > from those member functions.

You say that you "have to" design those iterators. Why do you "have to"?
What's the driving force behind it?

Victor
 
M

Mike Wahler

Alexander Stippler said:
Hi,

I have to design some two dimensional iterators and I'm not quite sure about
the design. I'd like to have the iterators mostly STL-like. The STL does
not contain two dimensional iterators, I think. I'm not sure, what is the
best way of design and usage syntax.
Is there a good reference or example online? How could such an iterator look
like for the equivalent of std::vector, lets say my::matrix to "exploit"
the pointers as iterators like std::vector does?

A dereference of an iterator can return another iterator.

Consider this example using std::vector:

#include <iostream>
#include <vector>

int main()
{
typedef std::vector<int>::iterator it_dim2;
typedef std::vector<std::vector<int> >::iterator it_dim1;

std::vector<std::vector<int> > vec2d(3, std::vector<int>(5));

for(it_dim1 it1 = vec2d.begin(); it1 != vec2d.end(); ++it1)
for(it_dim2 it2 = it1->begin(); it2 != it1->end(); ++it2)
std::cout << '[' << it1 - vec2d.begin() << ']'
<< '[' << it2 - it1->begin() << ']'
<< " == " << *it2
<< '\n';

return 0;
}


-Mike
 
A

Allan Odgaard

Alexander Stippler said:
I have to design some two dimensional iterators and I'm not quite sure about
the design. I'd like to have the iterators mostly STL-like. The STL does
not contain two dimensional iterators, I think. I'm not sure, what is the
best way of design and usage syntax. [...]

It really depends on what you wish to store in this container.

E.g. you could just use a normal std::vector and add extra begin/end
member functions which take an integer (being the row) which then
return an iterator for that particular row.

That way you can e.g. extract row 7 with:

your::container<value_type> c(...);
std::vector<value_type> v(c.begin(7), c.end(7));

or use an appropriate stl-algorithm...

This way you may also invoke algorithms on the entire container using
begin/end without the row number, or you can iterate from e.g. row 7,
column 3 to row 9 column 10 using:

transform(c.begin(7) + 3, c.begin(9) + 10, ...);

This however will not work if you wish to iterate over a sub
'rectangle' of your container. E.g. if it contains a picture and you
wish to apply a filter to a subsection of this image, you most likely
would like the iteration to go from line n to m and visit columns j to
k.

For this I would suggest introducing an adapter similar to:

const your::subsection& s = c.subsection(n, m, j, k);
transform(s.begin(), s.end(), ...);

Another thing to think about is creating your container from a 1D
structure (which will probably become an issue, as all stl algorithms
are rather one dimensional), e.g. you could create a template
constructor taking 2 iterators and a column width, and it would then
insert it as 2D.

Hope it helps, despite the limited info on what you need to store in
this 2D container and what you intent to use it for...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top