D traits - Список интегральных членов данных
Я пытаюсь использовать следующий код, чтобы получить список интегральных членов данных из класса:
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()
Как мне сделать этот код скомпилированным?
1 ответ
Несмотря на то, что функция будет выполняться только во время компиляции в этой программе, она все равно должна быть скомпилирована как функция, которая может выполняться во время выполнения.
Вы должны объявить
allMembers
как явная константа:enum allMembers = __traits(allMembers, D);
allMembers
это кортеж Если вы используетеauto
, он будет сохранен как кортеж строк в "стеке", став значением времени выполнения, таким образом недоступным для оценки времени компиляции для__traits
,Вам нужно использовать
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);
}
}