Summary: foreach with ranges doesn't support opSlice()
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD

--- Comment #0 from Ali Cehreli <> 2011-02-17 14:19:37 PST ---
TDPL mentions a very useful feature on page 381 under "12.9.1 foreach with
Iteration Primitives".

(Note: I am copying all of this manually; the typos are mine):

It first shows a function that includes a possible "compiler rewrite" of a
foreach loop:

void process(SimpleList!int lst) {
    for (auto __c = lst; !__c.empty; __c.popFront()) {
        auto value = __c.front;
        ... // Use value of type int

It then says

.... if the iterated object offers the slice operator with no arguments lst[],
__c is initialized with lst[] instead of lst. This is in order to allow
"extracting" the iteration means out of a container without requiring the
container to define the three iteration primitives.

I couldn't get that to work with the following code:

import std.stdio;

struct MyRange
    int theOnlyOne;

    @property bool empty() const
        return false;

    @property ref int front()
        return theOnlyOne;

    void popFront()

struct MyCollection
    MyRange opSlice() const
        return MyRange();

void main()
    auto coll = MyCollection();

    foreach (i; coll) {            // <-- compilation error
        // ...

Error: cannot infer type for i

Providing the type of i as 'int' or 'ref int' produce a different error:

    foreach (int i; coll) {


    foreach (ref int i; coll) {


Error: no property 'opApply' for type 'MyCollection'

Please note that taking a slice explicitly works:

    foreach (i; coll[]) {

but not the feature mentioned in TDPL.

Thank you,

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to