On Thursday, 5 March 2020 at 18:33:41 UTC, Adam D. Ruppe wrote:
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.
Thanks for your reply:)
I don't need an alias at all. I was trying to figure something
out with opDispatch first but something like __traits(getMember,
obj, name)(args); never occurred to me. Awesome!
The handle knows whether or not it's valid and where to find the
object and it only makes sense in the context of the factory that
made it.
The template opDispatch looks like what I was looking for :)