Iterators for D
Walter Bright
newshound at digitalmars.com
Mon Nov 6 18:26:35 PST 2006
Kirk McDonald wrote:
> Walter Bright wrote:
>> You've always been able to:
>> int* p;
>> p[1] = ...
> Wouldn't that be p[0] = ...?
I must have misunderstood you. I thought you were asking if [n] worked
on pointers. Yes, it does.
> Is that how you intend to use opIndex to "dereference" the iterator?
> That's /terrifying/. Although it is consistent with pointers, using [0]
> for everything is just asking for trouble with regards to
> non-random-access iterators. And though it's probably not totally
> meaningless to a random reader of the code, it comes pretty darned close.
I agree it might be startling at first because it's unusual. Once one is
past that, however, is it that bad?
>>> If a class provides .begin, .end, and opApply, one of the two
>>> iteration methods has to take precedence. I would hope it's opApply.
>>
>> I was leaning towards the other way around.
>>
>
> It is slightly easier and clearer to explicitly say:
>
> foreach(e; t.begin) { }
>
> than
>
> foreach(e; &t.opApply) { }
>
> opApply is an operator overload. .begin would just be a special method.
> I would expect the operator to take precedence.
The:
foreach(e; t.begin) { }
would not be supported. It would be:
foreach (e; t) { }
If an aggregate had both, and iterators would be chosen by default,
overriding with:
foreach (e; &t.opApply) { }
would not require any new conventions or syntax. So I think this is the
right way to go.
>>> For a type T, its associated iterator type should be available via
>>> T.iterator. This has to be standard.
>>
>> It's not needed, as typeof(T.begin) will do it.
>>
>
> Due to the way in which D's type inference from properties works, you'll
> need typeof(T.begin()). Otherwise, it will derive the type of the method
> itself. (Which isn't even a valid type, as such.)
Yes, you're right.
>> No. opIndex()
>
> I'm referring specifically to the no-index form of opSlice (meaning i[]
> would "dereference" the iterator). (A no-index opIndex doesn't work.)
> This of course is inconsistent with pointers, so saying i[0] is better
> on that count.
Ok, I understand now where you were coming from with the slice.
>>> I opPostInc()
>>
>> Probably opAddAssign()
>
> Oh, there's another one:
>
> int opEquals(I)
Yes, I'd overlooked that.
>> I could go either way with that.
> Neither one is particularly elegant.
True, but that inelegance is hidden away in the library, but the
flexibility is probably worth it.
>> I think it does provide enough, in fact, it will be less wacky than in
>> C++ (look at the wretched iterator/const_iterator dichotomy). It'll
>> work with core arrays, and will not need those typedefs.
> Without the ability to overload the dereference operator, any attempt to
> write a class that behaves like a pointer in D will be unwieldy, or at
> least ugly. Admittedly, this isn't much of an issue when just using
> foreach, but might be an issue with any kind of STL-like algorithms
> library. (Which is what you're inviting when using C++'s iterator
> semantics.)
I still think it isn't necessary, but you might be thinking of a use
case I haven't. Can you provide an example?
More information about the Digitalmars-d
mailing list