模板化的多维数组 [英] Templated Multi-Dimensional Arrays
问题描述
我试图使用模板进行实验,并试图执行模板阵列,这东西可以声明如下:
阵列(浮球,3,2,1)myArray的!;
我已经通过用C这个问题的几种实现浏览+ +,但我似乎无法将其转换为D,因为我有语言(有D)的经验。
反正这些都是我试过的东西,遗憾的是他们没有工作:
1。编译时间函数 - 生成格式code
数据类型[D0] [D1] ... [DN]标识符
进口std.conv;静态字符串generateArray(D ...)(字符串类型,字符串标识,D尺寸)
{
字符串结果=类型; 的for(int i = 0; I< dimensions.length;我++)
{
结果〜=[〜来(字符串)(尺寸[I])〜!];
} 结果〜=〜标识符〜;; 返回结果;
}INT主要(字串[] args)
{
枚举DEB = generateArray(浮动,数据,3,2,1);
编译(味精,DEB); 返回0;
}
我可以包装成一个简单的Array类
类Array(T,D ...)
{
混入(generateArray(T,数据,D));
}
但是,这code失败:
./ template_recursion.d(10):错误:变量i无法在编译时读
./template_recursion.d(18):错误:模板实例template_recursion.expandTuple(INT,INT,INT)错误实例化
./template_recursion.d(18):错误:CTFE失败,因为expandTuple previous错误
2。递归模板 - 为说明这早些时候,我已经看到了实现在C ++中,但我似乎无法对这些语句转换成能在D编译器接受
<一个href=\"http://stackoverflow.com/questions/7058098/variadic-templates-multidimensional-array-container\">Variadic用C ++模板
模板&LT; T类,签名......(未做)&GT;结构数组;模板&LT; T类,无符号PrimaryD&GT;
结构数组&LT; T,PrimaryD&GT;
{
typedef的T类[PrimaryD]
类型数据;
夯;运算符[](无符号I){返回数据[I] }};模板&LT; T类,无符号PrimaryD,无符号......(未做)&GT;
结构数组&LT; T,PrimaryD,(未做)...&GT;
{
的typedef typename的阵列&LT; T,(未做)...&GT; ::类型OneDimensionDownArrayT;
typedef的OneDimensionDownArrayT键入[PrimaryD]
类型数据;
OneDimensionDownArrayT&安培;运算符[](无符号I){返回数据[I] }
};
首先code,使用混合类型:
尺寸
是 AliasSeq
(又名 TypeTuple
,用词不当,因为这其中蕴含的整数),它们只能在编译时已知值被编入索引,你的循环运行时不提供。
您可以,但是,使用编译时foreach循环,因为这样的:
的foreach(自动尺寸;尺寸){
结果〜=[〜来(字符串)(尺寸[I])〜!];
}
二code,使用模板:
模板的MultiArray(基本类型,Dimentions ...){
静若(Dimensions.length == 0)
别名的MultiArray =基本类型;
其他
!别名的MultiArray =的MultiArray(BASETYPE [尺寸[0],尺寸[1 .. $]。
}
I'm trying to experiment with templates and tried to implement templated arrays, something that can be declared like:
Array!(float, 3, 2, 1) myArray;
I've browsed through several implementations of this problem in C++ but I can't seem to convert it to D as I have little experience with the language (with D).
Anyways these are the stuff I tried, unfortunately none of them worked:
1. Compile-Time Functions - to generate code of the format
"DataType[D0][D1]...[Dn] Identifier"
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;
}
Which I can wrap into a simple Array class
class Array(T, D...)
{
mixin(generateArray(T, "Data", D));
}
But this code fails with:
./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. Recursive Templates - as stated earlier I have seen implementations of this in C++, but I can't seem to transform those statements into something the D compiler accepts.
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]; }
};
First code, using mixins:
dimensions
is an AliasSeq
(aka TypeTuple
, a misnomer because this one contains integers), which can only be indexed with values known at compile time, which your runtime for loop doesn't supply.
You can, however, use a compile-time foreach loop, as such:
foreach(auto dimension; dimensions) {
result ~= "[" ~ to!(string)(dimensions[i]) ~ "]";
}
Second code, using templates:
template MultiArray(BaseType, Dimentions...) {
static if(Dimensions.length == 0)
alias MultiArray = BaseType;
else
alias MultiArray = MultiArray!(BaseType[Dimensions[0]], Dimensions[1..$];
}
这篇关于模板化的多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!