RFC on range design for D2
Steven Schveighoffer
schveiguy at yahoo.com
Tue Sep 9 17:04:20 PDT 2008
"Andrei Alexandrescu" wrote
> Steven Schveighoffer wrote:
>> Let me explain by example:
>>
>> HashMap!(uint, myResource) resources;
>>
>> ....
>>
>> // returns something that allows me to later remove the element
>> auto r = resources.find(key);
>>
>> useResource(r);
>>
>> resources[newkey] = new myResource;
>>
>> resources.erase(r);
>>
>> Now, assuming that adding the new resource rehashes the hash map, what is
>> in r such that it ONLY points to the single resource? A marker saying
>> 'only one element'? Perhaps you just deleted a range you didn't mean to
>> delete, when you only wanted to delete a single resource. Perhaps r is
>> now considered 'invalid'. Granted, this example can be fixed by
>> reordering the lines of code, and perhaps you don't care about the
>> penalty of looking up the key again, but what if I want to save the
>> iterator to the resource somewhere and delete it later in another
>> function? And what if the cost of lookup for removal is not as quick?
>>
>> I think with a range being the only available 'iterator' type for certain
>> containers may make life difficult for stuff like this. I really don't
>> think iterator is the right term for what I think is needed, what I think
>> is needed is a dumbed down pointer. Something that has one operation --
>> opStar. No increment, no decrement, just 'here is a reference to this
>> element' that can be passed into the container to represent a pointer to
>> a specific element.
>
> I understand. My design predicates that you can't model such non-iterable
> iterators. Either you can use it to move along, in which case ranges will
> do just fine, or you can't, in which case my design doesn't support it.
>
> Note that the STL does not have non-iterable iterators. I think
> constructing cases where they make sense are tenuous.
Well, STL happens to use iterators to specify elements. It doesn't mean
that the iterators are used as iterators in that context, it's just that
it's easier to specify one type that does iteration AND represents position
:)
For example, std::list defines multiple erase functions:
iterator erase(iterator first, iterator last);
iterator erase(iterator position);
In the second case, the iterator need not support incrementing or
decrementing (to the user anyway), just referencing. They just used
iterator because it's already there :)
But in your proposed scenario, I can't have the second function, only the
first. My example shows a case where I'd want the second function. What I
basically want is a range type where the upper limit is specified as 'always
null', so that iterating the range once always results in an empty range,
even if the container has changed topology.
-Steve
More information about the Digitalmars-d-announce
mailing list