www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Overloads

reply =?UTF-8?B?TcOhcmNpbw==?= Martins <marcioapm gmail.com> writes:
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?
Jun 26 2016
parent ArturG <var.spool.mail700 gmail.com> writes:
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
Jun 26 2016