[Insight-developers] Iterators & "operator *"

Gert Wollny gert at die.upm.es
Tue May 20 11:09:05 EDT 2008


Hello Luis, 

Am Montag, den 19.05.2008, 15:14 -0400 schrieb Luis Ibanez:
> Yes, the dereferoperator*() was purposely not used because it has an 
> inherent ambiguity between the "Get" and "Set" operations.
Which is the idea of STL iterators - to make them behave like pointers.

As a side note: Why is the "Set()" method declared "const"? Set does
change the state of the iterator, i.e. the value pointed to. By removing
it one could also get rid of that ugly const_cast<> inside.

> As you already pointed out, ImageAdaptors are part of the reason
> why we need to keep the Get/Set interface for the iterators.
Then there should probably some compile-time check in the Value()
functions, to see whether the active ImageAdaptor is just a pass-through
and if not, let compilation fail if the function is instanciated. (Would
require partial specialisation.)

> ITK iterators are "smarter" than STL iterators, in the sense that
> they know a lot more about the object they are iterating. This
> could also be seen as an encapsulation breach...  :-/
> 
> One STL-style operation that will be particularly inefficient
> if implemented with ITK iterators is the typical while-loop:
> 
>     while( iter != image->end() )
>       {
>       *iter = value;
>       ++iter;
>       }
> The call to end() will result in a construction of an iterator
> at every call. The comparison != will require to compare the
> index location of the iterator in the image.

IMHO the idea of STL algorithms is to avoid this kind of while loop.
Above code would then read:

     fill(image->begin(), image->end(), value); 

which only leaves the (implicit) != comparison. 

Q: Talking about itkImage(Const)Iterator, you compare 
 (m_Buffer + m_Offset) != (it.m_Buffer + it.m_Offset)
Does this make sense? m_Buffer and it.m_Buffer will only be different,
if the iterators are constructed using different images, and unless one
can define images with overlapping memory locations,

  (m_Buffer != it.m_Buffer && 
     (m_Buffer + m_Offset) == (it.m_Buffer + it.m_Offset))  == true 

would be a bug.
If (m_Buffer == it.m_Buffer) would indeed be a requirement for a
valid comparison of this type of iterator, then operator != would reduce
to comparing the offsets which would make this call just as cheap as a a
call to IsAtEnd().
Asserting (m_Buffer == it.m_Buffer) should then, of course, be added
in debug builds.

> The basic reason why Iterators in ITK use a different design
> is that one image can be visited in many different ways, and
> we found useful to make possible the use of many types of
> iterators with a given image, instead of having the image
> define a single type of iterator.
Amen to that. 

> Attempting to use ITK iterators in STL algorithms may work
> in very particular cases, *if* we add to the ITK iterator
> all the concept checks that are required by the STL algorithm
> using the iterator. It may be interesting to give it a try..  :-)
I guess I'll check it out. I'm just too used to the STL and BOOST ...
Adding the necessary traits is quite easy, just requires some template
specialisation or deriving from the proper iterator. 

Best,

  Gert




More information about the Insight-developers mailing list