opDispatch

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Dec 25 08:04:32 PST 2014


On Thursday, 25 December 2014 at 15:50:07 UTC, Danny wrote:
> struct X {
> 	int a;
> }
> class Foo {
> 	X value;
> 	template opDispatch(string s) {
> 		value.opDispatch!(s) opDispatch;

That won't work anyway since X doesn't implement opDispatch - it 
needs to be written in the function by the user to be used.

opDispatch is a function called when a member isn't found. So 
with yours:

Foo.value -> value is found, so opDispatch is never called.

Foo.a -> value not found, the compiler tries Foo.opDispatch!"a". 
If that compiles, it works. Otherwise, it issues the "has no 
property" error.



A few tips with opDispatch:

* since you just get "no such property" if it fails, you don't 
know *why* it failed. To get a better error message when you know 
it should be working but isn't, try writing it out yourself:

foo.opDispatch!"a";

and the compiler will give you more information about why it 
didn't work.

* opDispatch is often a function. It doesn't have to be, but it 
usually is:

auto opDispatch(string name)() {
    return something;
}


> Is there another way to make Foo forward all unknown things to 
> X ?

You could try writing:


auto opDispatch(string name)() {
    return mixin("value." ~ name);
}


That would do it.


There is also alias this and opDot that does forwarding. I can't 
find the docs for them right now but add "alias value this;" to 
your class for one option or.... I think "X* opDot() { return 
&value; }" for the other.

alias this forwards any unknown properties to another member and 
also allows implicit conversion. It is kinda like how inheritance 
from a base class works.

opDot is an older function that might be removed at some point, 
it predates opDispatch and alias this, but what it does is 
forward to a return value when it isn't found.


More information about the Digitalmars-d-learn mailing list