Mimicking C++'s indexing behavior in D associative arrays

Rikki Cattermole via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Feb 17 17:39:56 PST 2015


On 18/02/2015 1:21 p.m., Matt Kline wrote:
> In C++, the index operator for maps will either return a reference to
> the existing value if the key can be found, or a reference to a new,
> default-initialized value if one with the given key cannot be found.
>
> In D, an exception is thrown instead when a value with the given key
> cannot be found, similar to unordered_map::at in C++. So if I want to
> mimic the same behavior (get or initialize to default), I have to do
> something like
>
> // Assume bar is some associative array of type Foo[string]
> Foo* value = key in bar;
> if (value) {
>      bar[key] = Foo.init;
>      value = &bar[key];
> }
> This seems sub-optimal, given that in involves three hashes (two lookups
> and one insertion). Is there a more efficient or cleaner way to do so?

So basically:

Foo v = bar.get(key, Foo.init)
bar[key] = v;

Get is like an ordinary index but it will return the given value if it 
does not exist in the AA.

Of course you probably want to create a new UFCS function to wrap your 
check + default initialize if it doesn't exist.

T grab(T, U)(T[U] aa, U key) if (is(T == struct)) {
     if (key !in aa)
         aa[key] = new T;
     return aa[key];
}

So:
Foo*[string] bar;
Foo v = *bar.grab("mykey");


More information about the Digitalmars-d-learn mailing list