[Insight-developers] Iterators & "operator *"
Luis Ibanez
luis.ibanez at kitware.com
Tue May 20 13:41:38 EDT 2008
Hi Gert,
1) Const correctness in ITK is managed via the implementation
of the two class variants, for example:
ImageRegionConstIterator
ImageRegionIterator
where the second derives from the first one.
The const iterators does not have Set() method,
only the non-const iterator does.
The reason why the Set() method is constant is
that it changes the content of the image, not
the content of the iterator.
It is analogous to the case
a) int const * t;
versus
b) int * const t;
where (a) is a non-const pointer to a const object
while (b) is a const pointer to a non-const object.
The state of an ITK image iterator is given by its
position in the image, not by the content of the image.
That's the reason for defining the Set() method as const.
It is true that the const_cast<> is ugly though...
2) Unfortunately we can not use partial specialization
in ITK, because we still support the Visual Studio 6.0
compiler.
If you would like to comment against or in favor of
dropping support for this compiler, please add your
comments to the following Wiki page:
http://www.itk.org/Wiki/Proposals:Dropping_Support_for_Visual_Studio_6.0
3) Yes, the use of STL iterators inside algorithms often
requires only one call to the container.end() method.
4) You seem to be right on your suggestion for replacing
the != operation between iterators to ask for:
a.buffer != b.buffer ||
a.offset != b.offset
In principle in ITK we don't have filters that create
images with overlapping memory buffers, ... but...
we can't prevent a user from using such constructions.
Would you like to give it a try at implementing this
change, and submitting an Experimental build to the
ITK Dashboard ?
It will be an interesting change to try.
5) Yes, it will be great if you can extend the ITK iterators
to make them valid inputs to STL algorithms. It will be
a great paper for the Insight Journal, and upon revision
we could modify the toolkit accordingly.
Just keep in mind that we can only use full specialization
of templates.
Please let us know how it goes.
Thanks
Luis
-------------------
Gert Wollny wrote:
> 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