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

Mateusz Loskot mateusz at loskot.net
Tue Apr 10 14:41:23 PDT 2018


On 10 April 2018 at 23:06, Even Rouault <even.rouault at spatialys.com> wrote:
> 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:
>> >
>> > 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 didn't look at the iterators impl. yet.
I just looked at your example and wondered if there are proxies
- for GDAL/OGR, those could be necessary, I imagine.

I mean a proxy as an object that 'looks' like a reference.
It's often necessary to for (proxied) collections of objects that can not be
accessed directly, via regular pointers/references.

> 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.

auto&& is most useful when container<T>::reference returns a proxy object,
which would not bind to auto& (it would bind to auto const& though).

> 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.

At first, it seems like they model the input iterators, single-pass
iterator category
http://en.cppreference.com/w/cpp/concept/InputIterator

> 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.

Or, use like any input iterators, seems safe.

> 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...

Or reference-like proxy like std::vector<bool> does.

Best regards,
-- 
Mateusz Loskot, http://mateusz.loskot.net


More information about the gdal-dev mailing list