digitalmars.D - Referencing structs in a foreach
- Alf (40/40) Jul 22 2014 I am wondering what could be the mistake. When trying to modify
- Dicebot (8/11) Jul 22 2014 This allocates new array and copies struct values to it (as D
- Alf (11/22) Jul 23 2014 Thanks for your reply.
- Peter Alexander (8/17) Jul 23 2014 I'd recommend using std.range.only:
- Dicebot (2/2) Jul 22 2014 Also please post any further questions to
I am wondering what could be the mistake. When trying to modify the member of a struct from within a foreach, the changes are gone after leaving the loop. Code: import std.stdio; void test() { struct Foo { int a; int b; } struct Bar { Foo f1; Foo f2; } Bar bar = {{10, 20}, {10, 20}}; writefln("Before => f1.a: %d, f1.b: %d - f2.a: %d, f2.b: %d\n", bar.f1.a, bar.f1.b, bar.f2.a, bar.f2.b); foreach (ref f; [bar.f1, bar.f2]) { f.a++; f.b++; } writefln("After => f1.a: %d, f1.b: %d - f2.a: %d, f2.b: %d\n", bar.f1.a, bar.f1.b, bar.f2.a, bar.f2.b); } void main() { test(); } Should print: Before => f1.a: 10, f1.b: 20 - f2.a: 10, f2.b: 20 After => f1.a: 11, f1.b: 21 - f2.a: 11, f2.b: 21 But prints: Before => f1.a: 10, f1.b: 20 - f2.a: 10, f2.b: 20 After => f1.a: 10, f1.b: 20 - f2.a: 10, f2.b: 20 Thanks, Alf
Jul 22 2014
On Wednesday, 23 July 2014 at 01:31:48 UTC, Alf wrote:foreach (ref f; [bar.f1, bar.f2])This allocates new array and copies struct values to it (as D structs are value types). I think this should have been a compile-time error btw, it never makes sense to do ref iteration over an array literal for this very reason. Most likely you want to forced loop unrolling here and thus something like this:import std.typetuple; foreach (ref f; TypeTuple!(bar.f1, bar.f2))(don't pay attention to the weird "TypeTyple" name, it lies)
Jul 22 2014
Thanks for your reply. I figured an easier way would be to simply build an array of references: foreach (ref f; [&bar.f1, &bar.f2]) { f.a++; f.b++; } It seems to work just fine. Alf On Wednesday, 23 July 2014 at 01:41:33 UTC, Dicebot wrote:On Wednesday, 23 July 2014 at 01:31:48 UTC, Alf wrote:foreach (ref f; [bar.f1, bar.f2])This allocates new array and copies struct values to it (as D structs are value types). I think this should have been a compile-time error btw, it never makes sense to do ref iteration over an array literal for this very reason. Most likely you want to forced loop unrolling here and thus something like this:import std.typetuple; foreach (ref f; TypeTuple!(bar.f1, bar.f2))(don't pay attention to the weird "TypeTyple" name, it lies)
Jul 23 2014
On Wednesday, 23 July 2014 at 17:23:14 UTC, Alf wrote:Thanks for your reply. I figured an easier way would be to simply build an array of references: foreach (ref f; [&bar.f1, &bar.f2]) { f.a++; f.b++; } It seems to work just fine.I'd recommend using std.range.only: foreach (ref f; only(&x, &y)) { f.a++; f.b++; } Using array literals introduces the possibility of an unnecessary heap allocation. Using only will never allocate.
Jul 23 2014
Also please post any further questions to http://forum.dlang.org/group/digitalmars.D.learn instead
Jul 22 2014