[gdal-dev] Use of C++ iterators in API

Even Rouault even.rouault at spatialys.com
Tue Apr 10 14:06:55 PDT 2018


On mardi 10 avril 2018 22:34:56 CEST Mateusz Loskot wrote:
> On 10 April 2018 at 22:06, Even Rouault <even.rouault at spatialys.com> wrote:
> > Hi,
> > 
> > Just wanted to advertize the recent new introduction of C++ iterators
> > (...)
> 
> Good one, thanks!
> 
> >     for( auto&& poLayer: poDS->GetLayers() )
> 
> Do the iterators return a proxy reference hence the tutorial prefers
> auto&& over plain auto&?
> (ie. like std::vector<bool> iterator does)

Not completely sure to understand what a proxy reference is (C++11 stuff is 
still very new to me, and I don't pretend to master C++98, so ...), but I feel 
that must be close to what I have used in some cases, particularly wen 
iterating over fields of a features, or points of a linestring.

I read in some tutorial that using auto&& worked in all situations, including 
when the returned reference was const, so now I just use that everywhere.

In fact the nature of the object which is returned depends on the iterator, 
and as documented in the API, for the sake of implementation simplicity, those 
iterators do not necessarily respect the whole semantics of iterators.

That is if you do

auto iter = poLineString->begin();
OGRPoint& oPoint = *iter;
++iter;
OGRPoint& oAnotherPoint = *iter;
In fact &oAnotherPoint == &oPoint.

The reason is that internally a line string is not an array of OGRPoint, but 
an array of OGRRawPoint + optional array of z + optional array of m, so the 
iterator object only holds a single OGRPoint and always return the reference 
to it when you dereference it, and updates its content when you increment it.

So basically you should only use them in range based loops, where you don't 
really manipulate the iterator and cannot do stuff like the above.

I guess the "correct" solution would have been to return a OGRPointProxy that 
would keep a link to the linestring and the point index. But not sure how you 
would do that for a const iterator where the operator * is supposed to 
returned a const reference... Except allocating a std::array<OGRPointProxy> in 
the iterator, which seems overkill.

Improvements (if doable and not adding (too much) overhead to the underlying 
objects) are welcome of course.

Even

-- 
Spatialys - Geospatial professional services
http://www.spatialys.com


More information about the gdal-dev mailing list