【问题标题】:D traits - List of integral data membersD 特征 - 完整数据成员列表
【发布时间】:2014-10-06 23:24:02
【问题描述】:

我正在尝试使用以下代码从类中获取完整数据成员的列表:

import std.stdio;
import std.traits;

class D
{
    static string[] integralMembers = getIntegralMembers();

    static string[] getIntegralMembers()
    {
        auto allMembers = __traits(allMembers, D);

        string[] tmp = new string[allMembers.length];
        int ct = 0;

        for(int i = 0; i != allMembers.length; ++i) {
            bool isInteg = __traits(isIntegral, __traits(getMember, D, allMembers[i]));
            if(isInteg) {
                tmp[ct++] = allMembers[i];
            }
        }

        string[] ret = new string[ct];

        for(int i = 0; i != ct; ++i) {
            ret[i] = tmp[i];
        }

        return ret;
    }

    int a;
    this() { }
    ~this() { }
}

void main()
{
    auto integralMembers = D.integralMembers;

    foreach(mem; integralMembers)
    {
        writeln(mem);
    }
}

但是,编译失败并出现以下错误:

main.d(17): Error: variable i cannot be read at compile time
main.d(17): Error: expression expected as second argument of __traits getMember
main.d(19): Error: variable i cannot be read at compile time
main.d(7):        called from here: getIntegralMembers()

如何编译这段代码?

【问题讨论】:

    标签: d typetraits ctfe


    【解决方案1】:

    即使该函数仅在该程序内的编译期间运行,它仍必须可编译为可在运行时运行的函数。

    1. 您需要将allMembers 声明为清单常量:

      enum allMembers = __traits(allMembers, D);
      

      allMembers 是一个元组。如果您使用auto,它将作为字符串元组保存在“堆栈”上,成为运行时值,因此无法在编译时评估__traits

    2. 您需要使用foreach 而不是for。元组上的foreach 的特殊之处在于它将静态展开,因此__traits 将可以访问索引(和值)。

    固定程序:

    import std.stdio;
    import std.traits;
    
    class D
    {
        static string[] integralMembers = getIntegralMembers();
    
        static string[] getIntegralMembers()
        {
            enum allMembers = __traits(allMembers, D);
    
            string[] tmp = new string[allMembers.length];
            int ct = 0;
    
            foreach(i, member; allMembers) {
                bool isInteg = __traits(isIntegral, __traits(getMember, D, member));
                if(isInteg) {
                    tmp[ct++] = allMembers[i];
                }
            }
    
            string[] ret = new string[ct];
    
            for(int i = 0; i != ct; ++i) {
                ret[i] = tmp[i];
            }
    
            return ret;
        }
    
        int a;
        this() { }
        ~this() { }
    }
    
    void main()
    {
        auto integralMembers = D.integralMembers;
    
        foreach(mem; integralMembers)
        {
            writeln(mem);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-29
      • 2012-08-27
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多