Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 25, 2016 how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
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 |
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to grampus | 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 The way you access the memers of a struct is through the dot syntax. i.e. a.x = a.y; > Is there an easy way to access x and y by using a["x"] and a["y"] in this case "x" and "y" are strings so no. |
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to grampus | 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 You can't do that. There's a problem because the string passed is not known at compile-time, so the return type of "opIndex(string member)" cannot be inferred. It works only for one type: °°°°°°°°°°°°°°°°°°° import std.stdio; struct Something { int x,y; float z; int opIndex(string member) { alias T = typeof(this); foreach(m;__traits(allMembers, T)) if (m == member) { static if (is(typeof(__traits(getMember, T, m)) == int)) return __traits(getMember, T, m); } assert(0); } } void main(string[] args) { Something s; writeln(s["x"]); } °°°°°°°°°°°°°°°°°°° If you add a template parameter to opIndex then you can't call it with the array syntax so it becomes pointless to use an operator overload. |
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to grampus | 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
----
import std.stdio;
struct Something
{
int x, y;
float z;
auto opIndex()(string member) {
switch (member) {
case "x": return this.x;
case "y": return this.y;
case "z": return this.z;
default: assert(0);
}
}
}
void main(string[] args)
{
Something s;
writeln(s["x"]);
writeln(s["z"]);
}
----
|
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Sunday, 25 September 2016 at 09:01:44 UTC, Namespace wrote:
> ----
> import std.stdio;
>
> struct Something
> {
> int x, y;
> float z;
>
> auto opIndex()(string member) {
> switch (member) {
> case "x": return this.x;
> case "y": return this.y;
> case "z": return this.z;
> default: assert(0);
> }
> }
> }
>
> void main(string[] args)
> {
> Something s;
> writeln(s["x"]);
> writeln(s["z"]);
> }
> ----
Doesn't work. s["x"] is returned as float in this example. The reason is, opIndex cannot magically change return type based on the passed-in string.
|
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to grampus | 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
If they all share the same type, you can use a switch like @Namespace suggested.
If the "x" and "y" strings are available at compile-time, you can use a mixin.
auto getattr(string attr)(point a){
mixin(`return a.` ~ attr ~ `;);
}
auto x = a.attr!"x";
Otherwise, no. D types aren't dynamic in the same way that Python's types are.
|
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to pineapple | On Sunday, 25 September 2016 at 10:44:38 UTC, pineapple wrote:
> 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
>
> If they all share the same type, you can use a switch like @Namespace suggested.
>
> If the "x" and "y" strings are available at compile-time, you can use a mixin.
>
> auto getattr(string attr)(point a){
> mixin(`return a.` ~ attr ~ `;);
> }
>
> auto x = a.attr!"x";
>
> Otherwise, no. D types aren't dynamic in the same way that Python's types are.
Thank you all for the clear reply.
Now I know how far I can go on this.
|
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Sunday, 25 September 2016 at 09:01:44 UTC, Namespace wrote:
> 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
>
> ----
> import std.stdio;
>
> struct Something
> {
> int x, y;
> float z;
>
> auto opIndex()(string member) {
> switch (member) {
> case "x": return this.x;
> case "y": return this.y;
> case "z": return this.z;
> default: assert(0);
> }
> }
> }
>
> void main(string[] args)
> {
> Something s;
> writeln(s["x"]);
> writeln(s["z"]);
> }
> ----
I think this approach should work for me.
Thank you Namespace:)
|
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Sunday, 25 September 2016 at 09:01:44 UTC, Namespace wrote:
> 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
>
> ----
> import std.stdio;
>
> struct Something
> {
> int x, y;
> float z;
>
> auto opIndex()(string member) {
> switch (member) {
> case "x": return this.x;
> case "y": return this.y;
> case "z": return this.z;
> default: assert(0);
> }
> }
> }
>
> void main(string[] args)
> {
> Something s;
> writeln(s["x"]);
> writeln(s["z"]);
> }
> ----
WooW I have to say that I'm mesmerized !
How can this works ? "member" is run time variable so the return type shouldn't be inferable.
|
September 25, 2016 Re: how to access struct member using [] operator? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Sunday, 25 September 2016 at 16:07:59 UTC, Basile B. wrote:
> On Sunday, 25 September 2016 at 09:01:44 UTC, Namespace wrote:
>> 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
>>
>> ----
>> import std.stdio;
>>
>> struct Something
>> {
>> int x, y;
>> float z;
>>
>> auto opIndex()(string member) {
>> switch (member) {
>> case "x": return this.x;
>> case "y": return this.y;
>> case "z": return this.z;
>> default: assert(0);
>> }
>> }
>> }
>>
>> void main(string[] args)
>> {
>> Something s;
>> writeln(s["x"]);
>> writeln(s["z"]);
>> }
>> ----
>
> WooW I have to say that I'm mesmerized !
>
> How can this works ? "member" is run time variable so the return type shouldn't be inferable.
Ther's no trick related to compile time:
import std.stdio;
struct Something
{
int y;
float z;
double e;
float x = 1234;
auto opIndex()(const(char)[] member) {
switch (member) {
case "x": return this.x;
case "y": return this.y;
case "z": return this.z;
case "e": return this.e;
default: assert(0);
}
}
}
void main(string[] args)
{
Something s;
char[] member = "w".dup;
member[0] += args.length;
writeln(s[member]);
}
Can we get an explanation from a compiler guy ? It seems the the switch statement is already evaluated at compiled time...
|
Copyright © 1999-2021 by the D Language Foundation