模板化的多维数组 [英] Templated Multi-Dimensional Arrays

查看:127
本文介绍了模板化的多维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用模板进行实验,并试图执行模板阵列,这东西可以声明如下:

 阵列(浮球,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,使用混合类型:

尺寸 Alias​​Seq (又名 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.

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

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆