如何创建范围元组?

时间:2016-01-16 10:20:55

标签: d

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][]);

1 个答案:

答案 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);
      }
    }
}

有两点需要注意:

  1. 嵌套在模板中的函数允许我们只指定索引而不是类型。如果它只是auto tupIndexToRange(T, Indices)(T tup),我们必须明确提供类型。

  2. 我们通过调用.tupIndexToRange而不是tupIndexToRange来递归,因为我们想要通过外部作用域中的模板递归,而不是嵌套函数。