首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在编译时从现有列表构造列表

在编译时从现有列表构造列表
EN

Stack Overflow用户
提问于 2018-11-28 22:43:42
回答 1查看 54关注 0票数 0

我在程序的一个模块中有一个全局项目列表(每个项目都有几个属性)。它是不可变的,并且在代码中是静态定义的,所以不用担心。

例如,假设我有蔬菜,它只是一个别名,用name (字符串)、code (ubyte)和price (ushort)将它们定义为一个不可变的元组。

我希望能够通过namecode访问这些蔬菜,所以我认为既然蔬菜列表在编译时是已知的,那么我可以使用对这些蔬菜的引用(比如string=>vegetable和ubyte=>vegetable)来构造关联数组。

这就是我想要实现的东西:

代码语言:javascript
复制
static struct instructions
{
    // list of Veggies

    immutable instr[] list = [
        Veggie("Potato" , 0xD0, 2),
        Veggie("Carrot" , 0xFE, 5),
    ];


    // genByCode and genByName being pure functions that get CTFE'd
    // and return the desired associative array

    immutable instr[ubyte]  byCode = genByCode(list);
    immutable instr[string] byName = genByName(list);


    // overloaded function returns the right Veggie

    instr get(string name) const
    { return byName[name]; }
    instr get(ubyte  code) const
    { return byCode[code]; }

}

使用以下形式的生成器函数(为清楚起见将其分开)

代码语言:javascript
复制
pure instr[ubyte] genByCode(immutable Veggie[] list)
{
    instr[ubyte] res;
    foreach (i ; list)
        res[i.code] = i;
    return res;
}

我花了相当多的时间胡闹,但我不能去工作。当然,在运行时构造它是微不足道的,但显然它应该可以在编译时完成。

一开始我认为这是一个可变性的问题,所以我尝试将所有东西(蔬菜和蔬菜列表)标记为不可变的(因为它们本来就应该是不可变的),但后来我遇到了我认为是不可变的元组的问题,感觉太迷茫了,无法继续下去。

我可以从一个对这里的机制有更清晰的概述的人那里得到帮助吗?谢谢!

EN

回答 1

Stack Overflow用户

发布于 2018-12-02 04:38:37

数据已经存在,不需要构造编译时关联数组。

只需静态地迭代它:

代码语言:javascript
复制
static auto get(int code)(){
    static foreach(veggie; list)
        static if(veggie.code == code)
            return veggie;
}

...

void main(){
    writeln(instructions.get!0xD0);
}

它可能比通过散列映射进行访问慢,但这就是CTFE的生命周期。

要确保它在编译时求值,可以使用以下命令:

代码语言:javascript
复制
template get(int code){
    static foreach(veggie; list)
        static if(veggie.code == code)
            alias get = veggie;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53522023

复制
相关文章

相似问题

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