Call different member functions on object sequence with a generic handler function?

Basile B. b2.temp at gmx.com
Sat Jun 30 00:16:49 UTC 2018


On Friday, 29 June 2018 at 16:44:36 UTC, Robert M. Münch wrote:
> I hope this is understandable... I have:
>
> class C {
> 	void A();
> 	void B();
> 	void C();
> }
>
> I'm iterating over a set of objects of class C like:
>
> foreach(obj; my_selected_objs){
> 	...
> }
>
> The iteration and code before/afterwards always looks the same, 
> I need this iteration for many of the memember functions like 
> C.A() and C.B(), etc.
>
> foreach(obj; my_selected_objs){
> 	...
> 	obj.A|B|C()
> 	...
> }
>
> So, how can I write a generic handler that does the iteration, 
> where I can specify which member function to call?
>
> void do_A() {
> 	handler(C.A()); ???
> }
>
> void do_B() {
> 	handler(C.B()); ???
> }
>
> handler(???){
> 	foreach(obj: my_selected_objs){
> 		???
> 	}
> }
>
> Viele Grüsse.

Using opDispatch we can manage to get a voldemort able to resolve 
the member func A, B or C etc.

---
import std.stdio;

class C
{
     void A(){writeln(__FUNCTION__);}
     void B(int i){writeln(__FUNCTION__, " ", i);}
}

auto handler(T)(T t)
{
     struct Handler
     {
         auto opDispatch(string member, Args...)(Args args)
         {
             import std.algorithm.iteration : each;
             mixin( `t.each!(a => a.` ~ member ~ `(args));` );
         }
     }
     Handler h;
     return h;
}

void main()
{
     auto cs = [new C(), new C()];
     handler(cs).A();
     cs.handler.B(42); // UFCS style
}
---

which results a very natural expression.


More information about the Digitalmars-d-learn mailing list