【问题标题】:Templated Multi-Dimensional Arrays模板化多维数组
【发布时间】:2015-11-01 14:53:59
【问题描述】:

我正在尝试使用模板并尝试实现模板化数组,可以这样声明:

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]; }
};

【问题讨论】:

    标签: arrays d variadic-templates


    【解决方案1】:

    第一个代码,使用 mixins:

    dimensions 是一个AliasSeq(又名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..$];
    }
    

    【讨论】:

    • 两种解决方案都能完美运行,但我无法理解递归模板实例化的工作原理。别名 MultiArray = MultiArray!(BaseType[Dimensions[0]], Dimensions[1..$]; part.
    • 它递归调用MultiArray模板,在BaseTypeBaseType[Dimensions[0]])中添加一个定长数组部分,然后切掉我们刚刚添加的维度(Dimensions[1..$])跨度>
    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 2011-08-30
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多