digitalmars.D.learn - What is the correct way to forward method calls to the struct field?
- monnoroch (33/33) Jun 21 2014 I tried this:
- monnoroch (2/2) Jun 21 2014 Actyaly, last variant didn't work either: i was testing it
- monnoroch (3/5) Jun 21 2014 Oh, my bad, "alias impl this;" actually did work. But the first
- Philippe Sigaud via Digitalmars-d-learn (25/31) Jun 21 2014 You can use 'auto' to let the compiler deduce the return type. Here I
- monnoroch (4/4) Jun 22 2014 Thanks a lot!
- monnoroch (3/3) Jun 22 2014 There is also a problem: when i declare opDispatch to be private,
- Philippe Sigaud via Digitalmars-d-learn (4/7) Jun 22 2014 I don't know. I never used private in conjunction with a template.
- Philippe Sigaud via Digitalmars-d-learn (27/31) Jun 22 2014 You can test the mixin with static if, like this:
I tried this: struct S { R opDispatch(string name, R, Args...)(Args args) { return mixin("(*iface)." ~ name)(iface, args); } SomeT ** iface; } But then val.foo(1, 2) gives me "no property 'foo' for type 'S'". I've seen the template solution: struct S { template opDispatch(string name) { R opDispatch(R, Args...)(Args args) { return mixin("(*iface)." ~ name)(iface, args); } } SomeT ** iface; } But that does not seem to work anymore. I've tried then struct S { auto ifc() { return *iface; } auto ifc() const { return *iface; } SomeT ** iface; } And that worked, but it's not perfect: i also want to pass iface as a first argument. val.foo(1, 2) -> (*val.iface).foo(val.iface, 1, 2). Any suggestions?
Jun 21 2014
Actyaly, last variant didn't work either: i was testing it inside S like "ifc.foo(1)", so UFCS kiked in, not alias this.
Jun 21 2014
On Saturday, 21 June 2014 at 18:16:17 UTC, monnoroch wrote:Actyaly, last variant didn't work either: i was testing it inside S like "ifc.foo(1)", so UFCS kiked in, not alias this.Oh, my bad, "alias impl this;" actually did work. But the first argument problem still holds.
Jun 21 2014
You can use 'auto' to let the compiler deduce the return type. Here I use 'foo' which returns an int and 'bar', which returns void. struct SomeT { int foo(double d) { return 0;} void bar(double d) { return;} } struct S { auto /* here */ opDispatch(string name, Args...)(Args args) { return mixin("(*iface)." ~ name)(args); } SomeT** iface; } void main() { SomeT st; SomeT* st_p = &st; SomeT** st_p_p = &st_p; S s = S(st_p_p); import std.stdio : writeln; writeln(s.foo(3.14)); // "0" writeln(typeof(s.bar(3.14)).stringof); // "void" } On Sat, Jun 21, 2014 at 8:21 PM, monnoroch via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Saturday, 21 June 2014 at 18:16:17 UTC, monnoroch wrote:Actyaly, last variant didn't work either: i was testing it inside S like "ifc.foo(1)", so UFCS kiked in, not alias this.Oh, my bad, "alias impl this;" actually did work. But the first argument problem still holds.
Jun 21 2014
Thanks a lot! There is a problem though: when i pass incorrect parameters to such a method, it says, that S has no such field, which is a misleading error message.
Jun 22 2014
There is also a problem: when i declare opDispatch to be private, i still have access to this forwarding from another package. Is it a bug or what?
Jun 22 2014
On Sun, Jun 22, 2014 at 5:04 PM, monnoroch via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:There is also a problem: when i declare opDispatch to be private, i still have access to this forwarding from another package. Is it a bug or what?I don't know. I never used private in conjunction with a template. Let's hope someone more knowledgeable than me can answer this.
Jun 22 2014
On Sun, Jun 22, 2014 at 5:02 PM, monnoroch via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Thanks a lot! There is a problem though: when i pass incorrect parameters to such a method, it says, that S has no such field, which is a misleading error message.You can test the mixin with static if, like this: struct SomeT { int foo(double d) { return 0;} void bar(double d) { return;} } struct S { auto opDispatch(string name, Args...)(Args args) { static if (is(typeof(mixin("(*iface)." ~ name)(args)))) return mixin("(*iface)." ~ name)(args); else pragma(msg, "S." ~ name ~ " cannot be called with arguments of type " ~ Args.stringof); } SomeT** iface; } void main() { SomeT st; SomeT* st_p = &st; SomeT** st_p_p = &st_p; S s = S(st_p_p); s.foo(3.14); s.foo("abc"); s.bar("abc", 3.14); }
Jun 22 2014
Cool! Only this does not show me where the error was. __FILE__ and __LINE__ is not any help here, because it's a template. Any other way to find out where the actual error was?
Jun 22 2014
Nah, this gives me lots of compiler crap, like .empty and others, when compiler tries to compile them.
Jun 22 2014