www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - in a template argument, specify which object member to access?

reply cy <dlang verge.info.tm> writes:
object.member lets me access the member of the object, but what 
if I want to access those members in a generic way, but in a 
different arrangement depending on context? Like if I wanted to 
first follow a tree down, and second priority would be going left 
to right, but then I wanted to first go right, and second 
priority would be going down to up.

struct A {
	string up;
	string down;
	string left;
	string right;
}

template goPlaces(D1,D2,D3) {
	string go(A a) {
		return "go " ~ a.D1 ~ " then go " ~ a.D2 ~ " then go " ~ a.D3;
	}
}

import std.stdio;

void main() {
	A a = {"north","south","east","west"};
	writeln(goPlaces!(up,down,left)(a));
}

Do I just have to use a mixin? Or implement those members as 
indexes in an array, if I want to use them differently?

enum Way { UP, DOWN, LEFT, RIGHT };
struct A {
	string[Way.max+1] ways;
}
...
Feb 08 2016
next sibling parent reply Mengu <mengukagan gmail.com> writes:
On Monday, 8 February 2016 at 21:09:47 UTC, cy wrote:
 object.member lets me access the member of the object, but what 
 if I want to access those members in a generic way, but in a 
 different arrangement depending on context? Like if I wanted to 
 first follow a tree down, and second priority would be going 
 left to right, but then I wanted to first go right, and second 
 priority would be going down to up.

 [...]
i believe you can use __traits(getMember) there.
Feb 08 2016
parent reply cy <dlang verge.info.tm> writes:
On Monday, 8 February 2016 at 22:38:45 UTC, Mengu wrote:
 i believe you can use __traits(getMember) there.
Great! Should have refreshed before sending that reply... I wonder if mixin("a."~member) is better or worse than __traits(getMember,a,member)...
Feb 08 2016
next sibling parent cym13 <cpicard openmailbox.org> writes:
On Monday, 8 February 2016 at 22:46:06 UTC, cy wrote:
 On Monday, 8 February 2016 at 22:38:45 UTC, Mengu wrote:
 i believe you can use __traits(getMember) there.
Great! Should have refreshed before sending that reply... I wonder if mixin("a."~member) is better or worse than __traits(getMember,a,member)...
I think I prefer the mixin version because it doesn't rely on compiler internals and is easier to read IMHO but this is very questionable.
Feb 08 2016
prev sibling parent Mengu <mengukagan gmail.com> writes:
On Monday, 8 February 2016 at 22:46:06 UTC, cy wrote:
 On Monday, 8 February 2016 at 22:38:45 UTC, Mengu wrote:
 i believe you can use __traits(getMember) there.
Great! Should have refreshed before sending that reply... I wonder if mixin("a."~member) is better or worse than __traits(getMember,a,member)...
i think it's a matter of taste and here's how i would do it: import std.stdio; import std.array; struct A { string up; string down; string left; string right; } string goPlaces(args...)(A a) { string[] result; foreach (arg; args) { result ~= __traits(getMember, a, arg); } return "go " ~ result.join(" then go "); } void main() { A a = {"north", "south", "east", "west"}; writeln(goPlaces!("up", "down", "left")(a)); writeln(goPlaces!("down", "right", "left", "up")(a)); } // outputs // go north then go south then go east // go south then go west then go east then go north
Feb 08 2016
prev sibling parent cy <dlang verge.info.tm> writes:
This is what I have so far. Using mixin(rawstring~templatearg) 
for every time I access the member is kind of cludgy though.

struct A {
	string up;
	string down;
	string left;
	string right;
}

template goPlaces(string D1, string D2, string D3) {
	string goPlaces(ref A a) {
		mixin("a."~D2) = "deetoo";
		return "go " ~
			mixin("a."~D1) ~ " then go " ~
			mixin("a."~D2) ~ " then go " ~
			mixin("a."~D3);		
	}
}

void main() {
	import std.stdio;
	A a = {"north","south","east","west"};
	writeln(goPlaces!("up","left","down")(a));
	writeln(a.left);
}

top postinglol
On Monday, 8 February 2016 at 21:09:47 UTC, cy wrote:
 object.member lets me access the member of the object, but what 
 if I want to access those members in a generic way, but in a 
 different arrangement depending on context? Like if I wanted to 
 first follow a tree down, and second priority would be going 
 left to right, but then I wanted to first go right, and second 
 priority would be going down to up.

 struct A {
 	string up;
 	string down;
 	string left;
 	string right;
 }

 template goPlaces(D1,D2,D3) {
 	string go(A a) {
 		return "go " ~ a.D1 ~ " then go " ~ a.D2 ~ " then go " ~ a.D3;
 	}
 }

 import std.stdio;

 void main() {
 	A a = {"north","south","east","west"};
 	writeln(goPlaces!(up,down,left)(a));
 }

 Do I just have to use a mixin? Or implement those members as 
 indexes in an array, if I want to use them differently?

 enum Way { UP, DOWN, LEFT, RIGHT };
 struct A {
 	string[Way.max+1] ways;
 }
 ...
Feb 08 2016