模板化多维数组
Templated Multi-Dimensional Arrays
我正在尝试使用模板并尝试实现模板化数组,可以像这样声明:
Array!(float, 3, 2, 1) myArray;
我浏览了这个问题在 C++ 中的几个实现,但我似乎无法将其转换为 D,因为我对该语言(使用 D)的经验很少。
不管怎样,这些都是我尝试过的东西,不幸的是 none 成功了:
1。编译时函数 - 生成格式代码
"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;
}
我可以将其包装成一个简单的数组 class
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]; }
};
第一个代码,使用 mixins:
dimensions
是一个 AliasSeq
(又名 TypeTuple
,用词不当,因为它包含整数),它只能用编译时已知的值进行索引,您的运行时循环不提供。
但是,您可以使用编译时 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..$];
}
我正在尝试使用模板并尝试实现模板化数组,可以像这样声明:
Array!(float, 3, 2, 1) myArray;
我浏览了这个问题在 C++ 中的几个实现,但我似乎无法将其转换为 D,因为我对该语言(使用 D)的经验很少。
不管怎样,这些都是我尝试过的东西,不幸的是 none 成功了:
1。编译时函数 - 生成格式代码
"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;
}
我可以将其包装成一个简单的数组 class
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]; }
};
第一个代码,使用 mixins:
dimensions
是一个 AliasSeq
(又名 TypeTuple
,用词不当,因为它包含整数),它只能用编译时已知的值进行索引,您的运行时循环不提供。
但是,您可以使用编译时 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..$];
}