template tupIndexToRange(alias Tup, Indicies...){
import std.meta;
import std.typecons;
static if(Indicies.length == 0){
enum tupIndexToRange = tuple();
}
else{
enum tupIndexToRange = tuple(Tup[ Indicies[0] ][], tupIndexToRange!(Tup,Indicies[1..$]));
}
}
void main(){
alias Integrals = AliasSeq!(Array!int, Array!float, Array!double);
Tuple!Integrals integrals;
integrals[0].insertBack(1);
integrals[1].insertBack(2);
integrals[2].insertBack(3);
auto t = tupIndexToRange!(integrals, 0, 1, 2);
auto r = zip(t.expand);
}
错误:
source/app.d(119,34): Error: variable integrals cannot be read at compile time
source/app.d(119,33): called from here: tuple(integrals.__expand_field_2.opSlice(), Tuple())
source/app.d(119,56): Error: template instance app.main.tupIndexToRange!(integrals, 2) error instantiating
source/app.d(119,56): instantiated from here: tupIndexToRange!(integrals, 1, 2)
source/app.d(219,12): instantiated from here: tupIndexToRange!(integrals, 0, 1, 2)
我认为出现此错误是因为我试图在编译时访问该范围?我怎么告诉D我只需要在运行时访问该范围?
这是tupIndexToRange
应该做的事情:
auto t = tuple(integrals[0][], integrals[1][], integrals[2][]);
答案 0 :(得分:4)
我怎么告诉D我只需要在运行时访问该范围?
将其作为运行时参数传递:
template tupIndexToRange(Indicies...) {
auto tupIndexToRange(T)(T tup) {
static if(Indicies.length == 0){
return tuple();
}
else{
return tuple(tup[ Indicies[0] ][], .tupIndexToRange!(Indicies[1..$])(tup).expand);
}
}
}
有两点需要注意:
嵌套在模板中的函数允许我们只指定索引而不是类型。如果它只是auto tupIndexToRange(T, Indices)(T tup)
,我们必须明确提供类型。
我们通过调用.tupIndexToRange
而不是tupIndexToRange
来递归,因为我们想要通过外部作用域中的模板递归,而不是嵌套函数。