Accessing members through pointers to structs (also, CTFE associative arrays)

Ali via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Dec 13 12:30:17 PST 2016


Hi, Long time watcher and recently started playing with D a bit 
more. Ran in to a couple of snags that I'll combine in one post. 
It involves a data set that contains a list of strings. Each 
string represents a Room name. What I'm trying to do is pluck out 
the room names and also calculate the frequency each letter 
occurs in a name, per room.

First problem is to do with pointers to structs. Here's the code:

static immutable rooms = 
import("data.txt").split("\n").map!parse.array;

static Tuple!(const(Room*), "room", int[char], 
"frequencies")[rooms.length] data;
static this() {
     foreach (i, room; rooms) {
         data[i].room = &room;
         // Also calculate frequencies, but that's not important 
yet.
     }
}

void main() {
     foreach (d; data) {
         d.room.name.writeln; // <-- How do I access name here??
     }
}

I've tried d.(*room).name but that didn't work. There's no arrow 
operator. I've tried making my tuple a ref Room instead, but 
that's a no go as well. I can copy the Room object directly in to 
the tuple, but since it's already there in static immutable data 
I'd rather just have a pointer to it.

Is there a way to do that?

Second problem is to do with associative arrays. At first the 
Room object had a frequencies object in it (ie: int[char] <- 
number of times a character appears in the name).

In my parse function, if I add a foreach loop that loops through 
the letters in the room's name, and adds populates an associative 
array like so:

Room parse(string line) {
     immutable name = // blah
     int[char] frequencies;
     foreach (letter; name) {
         frequencies[letter] += 1
     }
     return Room(name, frequencies);
}

pragma(msg, rooms); // <- this works!

In the above case the pragma actually prints out all the Room 
objects, with their respective frequencies calculated correctly. 
But *after* it has printed it out, then a whole list of 
compilation errors that all look like this:

Error: non-constant expression ['d':1, 'r':3, 'x':1, 'e':1, 
'v':2, 'k':2, 'z':1, 't':1, 'u':1, 'p':2, 'c':1, 's':1, 'f':2, 
'i':2]

But it seems that it was calculated correctly, it just can't be 
assigned to the actual variable.

My current workaround includes taking frequencies out of the Room 
struct and calculating them inside a module constructor (hence 
the first question on the Tuple and Room *)

Are there other workarounds?

Cheers, and thanks for any help!
- Ali


More information about the Digitalmars-d-learn mailing list