3

我有以下范围:

struct Range {
  uint data;

  @property{
    bool empty() { return false; }
    uint front() { return data; }
    void popFront() { data = data * 2 + 1; }
  }
}

尝试使用它, foreach(c; Rnage()){ /*...*/ }工作,但foreach(i, c; Range()){ /*...*/ }我得到:

Error: cannot infer argument types

我需要i类似的东西foreach(i, v; [1,2,3,4]){ }

4

2 回答 2

8

范围不支持语法

foreach(i, c; range)

虽然这似乎很明显应该在简单的情况下工作,但该索引甚至应该是取决于范围的类型并且并不总是有意义。因此,foreach 不会自动提供索引计数器,范围也无法提供。

但是,由于使用 foreach 解包元组,您可以通过使用您的范围来完成:std.range.sequence std.range.zip

foreach (i, e; zip(sequence!"n"(), range))
{
}

顺便说一句,你不应该popFront@property. 这没有任何意义。popFront不接受任何参数并且不返回任何值。它根本不像一个变量。属性的重点是具有像变量一样起作用的函数。If/when-property的实现被完全整理出来并成为正常行为(目前它相当有问题,这就是为什么它目前是一个单独的开关的部分原因),popFront因为你定义它是不可用的。

于 2012-07-23T00:03:50.490 回答
2

如果您使用opApply实现范围,您可以为无索引样式和有索引样式重载一个版本:

struct Range {
    int opApply(int delegate(int) action){
        uint data=0;
        while(true){
            action(data);
            data=data*2+1;
        }
        return 0;
    }

    int opApply(int delegate(uint,int) action){
        uint i=0;
        foreach(element;this){
            action(i++,element);
        }
        return 0;
    }
}
于 2012-07-23T01:59:18.420 回答