On Sunday, 26 June 2016 at 11:23:14 UTC, Márcio Martins wrote:
Consider this snippet:
struct X {
int foo(Args...)(Args args) if (Args.length > 1) { return
Args.length; }
int foo() { return 0; }
int foo(int y) { return 1; }
alias Name = string;
int field_;
}
void listMembers(T)(ref T x) {
foreach (Member; __traits(derivedMembers, T)) {
pragma(msg, Member, " ", __traits(getOverloads, x,
Member).length);
//pragma(msg, __traits(getProtection, __traits(getMember,
x, Member))); // Error: argument string has no protection
}
}
void main() {
X x;
listMembers(x);
//auto fptr = &x.foo; // Error: x.foo(Args...)(Args args) if
(Args.length > 0) is not an lvalue
}
Output:
foo 0LU
Name 0LU
field_ 0LU
foo 0LU
Name 0LU
field_ 0LU
There seems to be a few problems here:
1. It seems like getOverloads is returning 0 for 'foo' - is
this a bug? Was expecting a 3 or at least a 2 if the template
would be ignored.
2. That alias breaks getProtection - is this bug? Seems like it
should be public.
These two make it quite hard to iterate over and collect info
about arbitrary aggregates.
I want to get a list of all *public* members, including
pointers to all public member functions and their overloads,
excluding template member functions. This is turning out to be
hard due to these "unexpected behaviors".
Is there anything else I can do?
__traits(getOverloads, x, Member).length works if you place the
template after a function of the overloads and then it returns 2.
it fails as soon as the first member of the overload set is any
template, so i guess it must be a bug.
e.g.
struct Fails
{
void foo()(){}
void foo(int){}
}
struct Works
{
void foo(int){}
void foo()(){}
}
__traits(getOverloads, Fails, "foo").length.writeln; // 0
__traits(getOverloads, Works, "foo").length.writeln; // 1