2015-11-01 35 views
2

我試圖用模板進行實驗,試圖執行模板陣列,一些可以聲明如下:模板化的多維數組

Array!(float, 3, 2, 1) myArray; 

我已經通過在C這個問題的幾種實現瀏覽++但我似乎無法將其轉換爲D,因爲我對該語言的經驗不多(使用D)。

反正這些都是我試過的東西,可惜沒有一次成功:

1.編譯時函數 - 生成格式

的代碼「數據類型[D0] [D1]。 .. [DN]標識符」

import std.conv; 

static string generateArray(D...)(string type, string identifier, D dimensions) 
{ 
    string result = type; 

    for(int i = 0; i < dimensions.length; i++) 
    { 
     result ~= "[" ~ to!(string)(dimensions[i]) ~ "]"; 
    } 

    result ~= " " ~ identifier ~ ";"; 

    return result; 
} 

int main(string[] args) 
{ 
    enum deb = generateArray("float", "data", 3, 2, 1); 
    pragma(msg, deb); 

    return 0; 
} 

其中我可以包裝成一個簡單的Array類

class Array(T, D...) 
{ 
    mixin(generateArray(T, "Data", D)); 
} 

但這個代碼失敗:

./template_recursion.d(10): Error: variable i cannot be read at compile time 
./template_recursion.d(18): Error: template instance template_recursion.expandTuple!(int, int, int) error instantiating 
./template_recursion.d(18): Error: CTFE failed because of previous errors in expandTuple 

2.遞歸模板 - 因爲說的這早些時候,我已經看到了實現在C++中,但我不能似乎這些語句轉換成能在d編譯器接受。

Variadic Templates in C++

template<class T, unsigned ... RestD> struct array; 

template<class T, unsigned PrimaryD > 
    struct array<T, PrimaryD> 
{ 
    typedef T type[PrimaryD]; 
    type data; 
    T& operator[](unsigned i) { return data[i]; } 

}; 

template<class T, unsigned PrimaryD, unsigned ... RestD > 
    struct array<T, PrimaryD, RestD...> 
{ 
    typedef typename array<T, RestD...>::type OneDimensionDownArrayT; 
    typedef OneDimensionDownArrayT type[PrimaryD]; 
    type data; 
    OneDimensionDownArrayT& operator[](unsigned i) { return data[i]; } 
}; 

回答

3

首先代碼,用混入:

dimensionsAliasSeq(又名TypeTuple,用詞不當,因爲這一個包含整數),它可以僅與在編譯時已知的值來索引,您的運行時for循環不提供。

你可以,但是,使用編譯時foreach循環,因爲這樣的:

foreach(auto dimension; dimensions) { 
    result ~= "[" ~ to!(string)(dimensions[i]) ~ "]"; 
} 

二代碼,使用模板:

template MultiArray(BaseType, Dimentions...) { 
    static if(Dimensions.length == 0) 
     alias MultiArray = BaseType; 
    else 
     alias MultiArray = MultiArray!(BaseType[Dimensions[0]], Dimensions[1..$]; 
} 
+0

這兩種解決方案完美地工作,但我不明白遞歸模板實例如何工作。 MultiArray = MultiArray!(BaseType [Dimensions [0]],Dimensions [1 .. $];部分 –

+0

它遞歸地調用'MultiArray'模板,將一個固定長度的數組部分添加到'BaseType'('BaseType [Dimensions [0]]'),然後切分我們剛剛添加的維度('Dimensions [1 .. $]') –