2014-10-06 19 views
5

Sto cercando di utilizzare il seguente codice per ottenere un elenco di membri di dati integrali dalla classe:tratti D - Elenco dei membri di dati integrali

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

Ma, la compilazione non riesce con questi errori:

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() 

Come faccio a compilare questo codice?

risposta

7

Anche se la funzione verrà eseguita solo durante la compilazione all'interno del programma, deve comunque essere compilabile come funzione che può essere eseguita in fase di esecuzione.

  1. è necessario dichiarare allMembers come una costante manifesta:

    enum allMembers = __traits(allMembers, D); 
    

    allMembers è una tupla. Se si utilizza auto, verrà salvato come una tupla di stringhe sullo "stack", diventando un valore di runtime, quindi inaccessibile alla valutazione in fase di compilazione per __traits.

  2. È necessario utilizzare foreach anziché for. foreach su una tupla è speciale in quanto si srotolare staticamente, quindi l'indice (e il valore) sarà accessibile a __traits.

programma fisso:

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