我有以下范围:
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]){ }
。
答案 0 :(得分:8)
范围不支持语法
foreach(i, c; range)
虽然看起来很明显这应该适用于简单的情况,但该指数甚至应该取决于范围的类型,并不总是有意义。因此,foreach不会自动提供索引的计数器,并且范围无法提供一个。
但是,感谢tuple unpacking with foreach,您可以使用std.range.sequence
std.range.zip
和您的范围来实现:
foreach (i, e; zip(sequence!"n"(), range))
{
}
顺便说一句,您不应该使用popFront
标记@property
。它没有任何意义。 popFront
不接受任何参数并且不返回任何值。它根本不像一个变量。而属性的关键是具有像变量一样的函数。如果{当-property
的实现被完全整理出来并且它变成了正常的行为(此时它有点错误,这是为什么它暂时是一个单独的开关的一部分),popFront
不会可以按照你的定义使用。
答案 1 :(得分:2)
如果使用opApply
来实现范围,则可以为without-index样式和with-index样式重载一个版本:
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;
}
}