How to dispatch a class function for an object accessed by handle?

Adam D. Ruppe destructionator at gmail.com
Thu Mar 5 18:33:41 UTC 2020


On Thursday, 5 March 2020 at 14:24:33 UTC, wjoe wrote:
> Implement this for free functions i would do something like this
>
> void dispatch(alias fn, ARGS...)(Handle handle, ARGS args)

Why do you need an `alias fn` like that?

My suggestion would be to just use the `opDispatch` magic method 
that gives you a string, then `__traits(getMember, obj, 
memberName)(args)` to call it.

But if you specifically need the alias param that won't work as 
well. (You could still do `__traits(getMember, obj, 
__traits(identifier, fn))` though, so it isn't ruled out 
entirely, just not as nice. That is also more likely to break 
with overloads btw)

struct Handle {
     private Whatever obj;

     auto opDispatch(string name, Args...)(Args args) {
           return __traits(getMember, obj, name)(args);
     }
}


And the usage would look like:

auto size = f.getSize(wallpaperhandle);


assuming the Handle knows how to store Whatever without being 
told what it is again at the call site (e.g. if you actually use 
an `interface` internally, or an encapsulated tagged union or 
whatever).

If you do need to tell it what it is, a two-level function gives 
that opportunity:


template opDispatch(string name) {
     auto opDispatch(T, Args...)(Args args) {
           auto obj = cast(T) o; // or whatever you do to convert
           return __traits(getMember, obj, name)(args);
     }
}

then the usage looks like

auto size = f.getSize!Bitmap(wallpaperhandle);


NOTE: opDispatch suppresses internal compile errors, it will just 
say "no such property whatever". you can explicitly instantiate 
with `f.opDispatch!"whatever` to help see better errors.

But it depends on what exactly you are doing.


More information about the Digitalmars-d-learn mailing list