2014-10-06 9 views
5

Я пытаюсь использовать следующий код, чтобы получить список целочисленных элементов данных из класса:D черта - Список интегральных элементов данных

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

Как это сделать?

ответ

7

Несмотря на то, что функция будет работать только во время компиляции внутри этой программы, она все равно должна быть скомпилирована как функция, которая может запускаться во время выполнения.

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