2016-01-16 2 views
3
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); 
} 

ERR:Как создать кортеж диапазонов?

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

ответ

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, так как мы хотим реорганизовать через шаблон во внешнем пространстве, а не вложенную функцию.

+0

Хотя теоретически возможно использовать псевдоним ... Мне любопытно узнать, есть ли у кого-то решение для этого. – rcorre