You're mixing compile-time and run-time logic here in a way that
D doesn't allow. In particular, isMutableString requires the
passed string to be a compile-time constant, and filter works on
run-time values.
There are a few different ways to resolve this. First, std.meta
has the Filter template, which behaves much in the same way as
std.algorithm.filter, but with compile-time tuples:
static foreach (field; Filter!(isMutableString,
FieldNameTuple!C)) {
writeln(field);
}
The other option is to rewrite isMutableString to work with
run-time values:
bool isMutableString(string field) {
switch (field) {
foreach (cField; FieldNameTuple!C) {
case cField:
return is(typeof(__traits(getMember, C, cField))
== string);
}
default:
return false;
}
}
static foreach(field; [FieldNameTuple!C].filter!(f =>
isMutableString(f))) {
writeln(field);
}
Both of these give the same output, and should be what you want.
--
Simen

You're mixing compile-time and run-time logic here in a way
that D doesn't allow. In particular, isMutableString requires
the passed string to be a compile-time constant, and filter
works on run-time values.

I just thought that filter() could be evaluated at compile time
too, as others function that I've used so far. Sometimes I don't
know if a native function can be evaluated at compile time until
I do enum x = func();

There are a few different ways to resolve this. First, std.meta
has the Filter template, which behaves much in the same way as
std.algorithm.filter, but with compile-time tuples:
static foreach (field; Filter!(isMutableString,
FieldNameTuple!C)) {
writeln(field);
}
The other option is to rewrite isMutableString to work with
run-time values:
bool isMutableString(string field) {
switch (field) {
foreach (cField; FieldNameTuple!C) {
case cField:
return is(typeof(__traits(getMember, C,
cField)) == string);
}
default:
return false;
}
}
static foreach(field; [FieldNameTuple!C].filter!(f =>
isMutableString(f))) {
writeln(field);
}
Both of these give the same output, and should be what you want.
--
Simen

That's exactly it! That Filter() from std.algorithm works like I
wanted :) nice solution also with rewrite the function to work
with run-time so that i can use with filter() but if I want to
have minimum runtime code to filter out immutable strings, the
first one is better right?

I just thought that filter() could be evaluated at compile time
too, as others function that I've used so far. Sometimes I
don't know if a native function can be evaluated at compile
time until I do enum x = func();

Yeah, it takes some getting used to what happens when and how
these interact. I can recommend H. S. Teoh's writeup:
https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time

if I want to have minimum runtime code to filter out immutable
strings, the first one is better right?

Indeed. It generates the equivalent code to just writing the
writeln()s you want, with no run-time overhead.
--
Simen