首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >D由枚举索引的直线数组

问D由枚举索引的直线数组
EN

Stack Overflow用户
提问于 2017-02-27 00:37:43
回答 2查看 308关注 0票数 0

在我的D程序中,我有一个固定长度的只读数组,我希望通过枚举类型对数组进行索引。

如果我做了这样的事

代码语言:javascript
复制
static const my_struct_t aray[ my_enum_t ] = ... whatever ...;

my_enum_t index;

result = aray[ index ];

然后,GDC生成的代码是巨大的,当数组被索引时,会充满对运行时的调用。因此,看起来要么将数组视为可变长度,要么将其视为关联数组(哈希表)或其他什么,而不是一个简单索引的固定长度的轻量级C型数组。因为枚举有固定的基数,不能增长,而且我有一个有限的稀疏值范围(我没有滥用关键字enum来定义大量随机常量),所以我不知道为什么会出现这种情况。

我通过将行改为

代码语言:javascript
复制
static const my_struct_t aray[ my_enum_t.max + 1 ]

据我理解,这意味着方括号中的值只是一个已知的积分型常数。由于索引现在根本不是枚举,所以现在有一个由整数索引的数组,因此我已经丢失了类型检查,所以可以使用任意随机整数类型变量对其进行索引,而不是确保只使用正确的(强)类型。

我该怎么做?

在更一般的情况下,(愚蠢的例子)

代码语言:javascript
复制
static const value_t aray[ bool ] = blah

例如,我的索引类型在语义上是完全合理的,但不只是一个无类型的size_t/int/uint --我假设我会遇到同样的问题。

我不想说这是一个编译器设计问题。这肯定是次优行为的一个例子。但是公平地说,对于编译器来说,究竟是要告诉它数组是固定长度还是变量,还是稀疏还是密集?我想要两件事:索引类型检查和非变量长度。实际上,在这个特定的情况下,数组是const (我也可以将它放在不可变的位置),所以它显然不可能是可变长度。但是,对于具有可修改内容但长度固定的数组,您需要能够声明它是固定长度的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-27 00:54:32

V[K] name是关联数组的语法,它确实执行运行时调用等操作,即使类型仅限于少量的值(如bool或枚举)。编译器可能会对其进行优化,使其作为一个简单的固定长度数组来实现,从而使它对程序的作用就像AA一样,但它没有这样做;它对所有关键类型的处理都是一样的。

我建议您使用启动的内容:T[enum.max + 1],但是如果您想要强制类型安全,则执行包装。如果只需要索引的一个实例,则可以使索引重载为静态:

代码语言:javascript
复制
enum Foo {
        one,
        two
}

struct struct_t {}

struct array {
        static private struct_t[Foo.max + 1] content;
        static struct_t opIndex(Foo idx) { return content[cast(int) idx]; }     
}

void main() {
        struct_t a = array[Foo.one];
}

然后,如果您想要更简单的重用,您可以简单地概括这一点。

代码语言:javascript
复制
struct enum_array(Key, Value) {
        static private struct_t[Key.max + 1] content;
        static Value opIndex(Key idx) { return content[cast(int) idx]; }
}

alias array = enum_array!(Foo, struct_t);

或者,当然,您不需要使它是静态的,您也可以执行一个常规的实例,并初始化内部的内容等等。

票数 2
EN

Stack Overflow用户

发布于 2017-02-27 00:55:50

在D中,静态数组和动态数组都由size_t索引,就像在C和C++中一样。你不能像在C或C++中那样改变D中索引的类型。因此,在D中,如果在数组声明的括号之间放置类型,则定义关联数组,而不是静态数组。如果您想要一个静态数组,您必须提供一个整数文本或编译时常量,并且没有办法要求一个裸露的静态数组被具有基本类型size_t或隐式转换为size_t的枚举类型索引。

如果要要求静态数组由size_t以外的类型索引,则需要将其包装在结构或类中,并通过成员函数控制对静态数组的访问。您可以重载opIndex以获取枚举类型,并将您的结构类型视为静态数组。因此,效果应该是您试图将枚举类型放入静态数组声明中的效果,但是它将是接受枚举值并使用它调用静态数组的成员函数,而不是对静态数组本身做任何事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42476071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档