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.

Reply via email to