www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - call member function alias

reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
if I have a member function alias and corresponding object and 
arguments, is there any way to turn them into a member function call?

e.g.

class X{
  void a();
}

auto profit(alias fn, T, Args...)(T t, Args args) {
   ???
}

profit!(X.fn, X)(x);

Constraints are:

1) must conserve ability to omit default arguments
2) if x is a subclass of X which overrides a, must not call overriden a.

I have mutually exclusive solutions for (1) and (2).

.. wait, nevermind. I can probably just wrap the two. It's an 
interesting problem, though, so I guess I'll post it.

For 1) just parse out the parameter list from typeof(&fn).stringof and 
mix it in as profit's arg list, and then just mixin x.a(paramids), but 
that won't counter D's virtual functions

For 2) hack together a delegate
dg.ptr = x;
dg.func_ptr = &fn;

but delegates don't support default arguments.
Aug 23 2012
parent reply Jacob Carlborg <doob me.com> writes:
On 2012-08-23 21:51, Ellery Newcomer wrote:
 if I have a member function alias and corresponding object and
 arguments, is there any way to turn them into a member function call?

 e.g.

 class X{
   void a();
 }

 auto profit(alias fn, T, Args...)(T t, Args args) {
    ???
 }

 profit!(X.fn, X)(x);

 Constraints are:

 1) must conserve ability to omit default arguments
 2) if x is a subclass of X which overrides a, must not call overriden a.

 I have mutually exclusive solutions for (1) and (2).

 .. wait, nevermind. I can probably just wrap the two. It's an
 interesting problem, though, so I guess I'll post it.

 For 1) just parse out the parameter list from typeof(&fn).stringof and
 mix it in as profit's arg list, and then just mixin x.a(paramids), but
 that won't counter D's virtual functions

 For 2) hack together a delegate
 dg.ptr = x;
 dg.func_ptr = &fn;

 but delegates don't support default arguments.

How about this: import std.stdio; class Foo { auto forward (alias fn, Args...) (Args args) { return fn(args); } void bar (int a = 3) { writeln("bar ", a); } } auto call (alias fn, T, Args...) (T t, Args args) { t.forward!(fn)(args); } void main () { auto foo = new Foo; call!(Foo.bar)(foo); call!(Foo.bar)(foo, 4); } Prints: bar 3 bar 4 Could this work for you? -- /Jacob Carlborg
Aug 23 2012
parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 08/23/2012 11:47 PM, Jacob Carlborg wrote:
 How about this:

 import std.stdio;

 class Foo
 {
      auto forward (alias fn, Args...) (Args args)
      {
          return fn(args);
      }

      void bar (int a = 3)
      {
          writeln("bar ", a);
      }
 }

 auto call (alias fn, T, Args...) (T t, Args args)
 {
      t.forward!(fn)(args);
 }

 void main ()
 {
      auto foo = new Foo;
      call!(Foo.bar)(foo);
      call!(Foo.bar)(foo, 4);
 }

 Prints:

 bar 3
 bar 4

 Could this work for you?

Nope :) class Zoo: Foo { override void bar(int a = 3) { writeln("Zoobar: ", a); } } auto zoo = new Zoo; call!(Foo.bar)(zoo,4); // prints Zoobar: 4 And anyways, my two solutions composed together quite nicely.
Aug 24 2012