www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Given an object, how to call an alias to a member function on it?

reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
How do I invoke the member function in a reliable way? Given 
`obj` of the type of the object, I used `mixin("obj.", 
__traits(identifier, memberFunc), "(params)")`, but that has 
issues, among probably others, definitely with visibility. (The 
member function alias is a template parameter.)
May 02 2023
next sibling parent reply ag0aep6g <anonymous example.com> writes:
On 02.05.23 14:52, Quirin Schroll wrote:
 How do I invoke the member function in a reliable way? Given `obj` of 
 the type of the object, I used `mixin("obj.", __traits(identifier, 
 memberFunc), "(params)")`, but that has issues, among probably others, 
 definitely with visibility. (The member function alias is a template 
 parameter.)
Construct a delegate from the alias and the object, and call that delegate: ---- class C { int field = 42; void method() { import std.stdio; writeln(field); } } void fun(alias method)(C c) { void delegate() dg; dg.funcptr = &method; dg.ptr = cast(void*) c; dg(); } void main() { fun!(C.method)(new C); /* prints "42" */ } ----
May 02 2023
parent reply Nick Treleaven <nick geany.org> writes:
On Tuesday, 2 May 2023 at 13:06:41 UTC, ag0aep6g wrote:
 void fun(alias method)(C c)
 {
     void delegate() dg;
     dg.funcptr = &method;
     dg.ptr = cast(void*) c;
     dg();
 }
This also works: void fun(alias method)(C c) { void delegate() dg = &c.method; dg(); }
May 03 2023
parent reply ag0aep6g <anonymous example.com> writes:
On 03.05.23 13:13, Nick Treleaven wrote:
 On Tuesday, 2 May 2023 at 13:06:41 UTC, ag0aep6g wrote:
 void fun(alias method)(C c)
 {
     void delegate() dg;
     dg.funcptr = &method;
     dg.ptr = cast(void*) c;
     dg();
 }
This also works: void fun(alias method)(C c) {     void delegate() dg = &c.method;     dg(); }
No, it doesn't. You're not using the alias. You're just accessing `c.method` directly. If the actual method weren't called "method", you'd get an error.
May 03 2023
parent Nick Treleaven <nick geany.org> writes:
On Wednesday, 3 May 2023 at 11:26:00 UTC, ag0aep6g wrote:
 On 03.05.23 13:13, Nick Treleaven wrote:
 void fun(alias method)(C c)
 {
      void delegate() dg = &c.method;
      dg();
 }
 
No, it doesn't. You're not using the alias. You're just accessing `c.method` directly. If the actual method weren't called "method", you'd get an error.
Sorry, you're right.
May 03 2023
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/2/23 8:52 AM, Quirin Schroll wrote:
 How do I invoke the member function in a reliable way? Given `obj` of 
 the type of the object, I used `mixin("obj.", __traits(identifier, 
 memberFunc), "(params)")`, but that has issues, among probably others, 
 definitely with visibility. (The member function alias is a template 
 parameter.)
Isn't that what `__traits(child)` is for? https://dlang.org/spec/traits.html#child -Steve
May 02 2023
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 2 May 2023 at 13:57:23 UTC, Steven Schveighoffer 
wrote:
 Isn't that what `__traits(child)` is for?

 https://dlang.org/spec/traits.html#child
Yes, __traits(child, object, method_alias)(args) is the way to do it.
May 03 2023
parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Wednesday, 3 May 2023 at 11:38:46 UTC, Adam D Ruppe wrote:
 On Tuesday, 2 May 2023 at 13:57:23 UTC, Steven Schveighoffer 
 wrote:
 Isn't that what `__traits(child)` is for?

 https://dlang.org/spec/traits.html#child
Yes, `__traits(child, object, method_alias)(args)` is the way to do it.
This doesn’t work, but a slight modification does the trick: ```d --- a.d #line 3 "a.d" // for run.dlang.io struct S { private void f() {} } alias Sf = S.f; --- b.d #line 12 "b.d" // for run.dlang.io import a; void main() { S s; __traits(child, s, Sf)(); // error: Error: struct `a.S` function `f` is not accessible (&__traits(child, s, Sf))(); // ok } ``` Thanks for making me aware of `__traits(child)`.
May 04 2023