opDispatch and @property setters

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jun 21 14:11:39 PDT 2016


On 06/21/2016 10:48 PM, Lodovico Giaretta wrote:
>      struct Wrapper(T)
>      {
>          private T wrapped;
>
>          template hasAssignableProperty(string name, Arg)
>          {
>              enum bool hasAssignableProperty = is(typeof(
>              (ref T val, ref Arg arg)
>              {
>                  mixin("val." ~ name ~ " = arg;");
>              }));
>          }
>
>          @property void opDispatch(string name, Arg)(Arg arg)
>              if (hasAssignableProperty!(name, Arg))
>          {
>              pragma(msg, "@property ", name, " ", Arg);
>              mixin("return wrapped." ~ name ~ " = arg;");
>          }
>          auto opDispatch(string name, Args...)(Args args)
>          {
[...]
>          }
>      }
[...]
>      struct Foo
>      {
[...]
>          int baz(int val) { return val; } // <-- method with exactly one
> argument
>      }
>
>      void main()
>      {
[...]
>          int bazres = wf.baz(42); // ERROR: no property 'baz' (it's
> trying to use the first opDispatch overload, while the second would be ok)
>      }
>
> Any way around this issue?

Works when you change the return type of the the @property opDispatch to 
auto, so that it can return the result. It's a little weird, but D does 
support calling functions with assignment syntax.

Alternatively, maybe you can actually check for the @property attribute 
in hasAssignableProperty. See FunctionAttribute/functionAttributes in 
std.traits [1]. I haven't tested this.


[1] http://dlang.org/phobos/std_traits.html#.FunctionAttribute


More information about the Digitalmars-d-learn mailing list