Struct initializer in UDA

Anonymouse zorael at gmail.com
Sun Sep 27 11:59:49 UTC 2020


On Sunday, 27 September 2020 at 10:17:39 UTC, realhet wrote:
> On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse 
> wrote:
>> On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:
>> The closest I can get is @(S.init.c(9).f(42)) with use of 
>> opDispatch, which is easier to read but still ugly.
>
> All I can get is that the
> - an identifier of a member is stronger than the opDispatch. -> 
> Error: function expected before (), not S(0, 0).c of type int
> - and if I prefix it with '_' it ruins toString. -> Error: no 
> property toString for type onlineapp.S
>
>
> import std.stdio, std.range, std.algorithm, std.traits, 
> std.meta, std.conv, std.string, std.uni, std.meta, 
> std.functional, std.exception;
>
> struct S{
>     int a, b;
>
>     auto opDispatch(string name, T)(T value)
>     if(name.startsWith("_"))
>     {
>         mixin(name[1..$], "= value;");
>         return this;
>     }
> }
>
> void main(){
>     S.init._a(5).writeln;
> }
>
>
> Now I'm more confused, as the compiler completely ignores the 
> if(name.startsWith("_")) constraint o.O

It works if you specialise opDispatch to take an int parameter 
instead of a type T. It smells like a bug but I don't know enough 
to say.

I used two opDispatches to be able to avoid having to use _a and 
_b, and std.algorithm.comparison.among to constrain them.

struct S{
     private int _a, _b;

     auto opDispatch(string name)(int value)
     if (name.among("a", "b"))
     {
         mixin("_", name, "= value;");
         return this;
     }

     auto opDispatch(string name)()
     if (name.among("a", "b"))
     {
        	mixin("return _", name, ";");
     }
}

void main(){
     S.init.a(123).b(456).writeln;
     S().b(456).a(123).writeln;  // Alternative syntax, may not 
work if opCall is defined
}

It's brittle in that you have to update and sync the two 
among("a", "b") constraints every time you add or remove a field, 
but I can't seem to get the names by introspection without it 
endlessly recursing over opDispatch again.


More information about the Digitalmars-d-learn mailing list