how to access struct member using [] operator?

ZombineDev via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Sep 26 07:11:51 PDT 2016


On Sunday, 25 September 2016 at 04:54:31 UTC, grampus wrote:
> Dear all
>
> For example, I have a struct
> struct point{int x;int y}
> point a;
>
> Is there an easy way to access x and y by using a["x"] and 
> a["y"]
>
> I guess I need to overload [], but can't figure out how.
>
> Someone can help? Thank you very much

Here's my solution. It's very similar to Namespace's solution, 
the main difference being that it doesn't coerce the result to 
the common type of all the fields which may not be always 
possible and is also looses information. It also uses 
this.tupleof and foreach, so you don't have to write the switch 
cases by hand.

```
struct Something
{
     int x, y;
     float z;
     string w;

     auto opIndex(string member)
     {
         import std.variant : Algebraic;
         import std.traits : Fields;
         alias FieldTypes = Fields!(typeof(this));
         alias CommonType = Algebraic!(FieldTypes, typeof(null));

         switch (member)
         {
             foreach (idx, field; this.tupleof)
             {
                 case this.tupleof[idx].stringof[5 .. $]:
                     return CommonType(this.tupleof[idx]);
             }

             default:
                 assert (0, "Type `" ~ typeof(this).stringof ~
                    "` doesn't contain any member named `" ~ 
member ~ "`!");
                 // or return CommonType(null);
         }
     }
}

void main()
{
     import std.stdio;
     auto s = Something(3, 4, 4.5, "asd");

     writeln(s["x"]);
     writeln(s["y"]);
     writeln(s["z"]);
     writeln(s["w"]);
     writeln(s["missing_field"]);
}
```

Application output:
3
4
4.5
asd

Application error:
core.exception.AssertError@/home/d623/f162.d(26): Type 
`Something` doesn't contain any member named `missing_field`!

The [5 .. $] trick is needed, because for e.g. idx = 0, 
this.tupleof[0].stringof returns "this.x" and we want to skip the 
"this." part (because otherwise the user would need to type 
s["this.x"]).


More information about the Digitalmars-d-learn mailing list