Modifying an associative array argument not passed by ref

Anonymouse zorael at gmail.com
Sat Mar 8 11:46:50 UTC 2025


If I want to have a function modify an associative array 
argument, when must I pass it by `ref` and when is it okay not to?

Concrete example;

```d
import std;

void modifyByRef(AA : V[K], V, K)(ref AA aa)
{
     aa[K.init] = V.init;
}

void modifyNoRef(AA : V[K], V, K)(/*ref*/ AA aa)
{
     aa[K.init] = V.init;
}

auto uniqueKey(AA : V[K], V, K)
     (/*ref*/ AA aa,
     K min = 1,
     K max = K.max,
     V value = V.init)
{
     auto id = uniform(min, max);
     while (id in aa) id = uniform(min, max);

     aa[id] = value;
     return id;
}

void main()
{
     int[int] aa;
     assert(0 !in aa);
     modifyByRef(aa);
     assert(0 in aa);

     int[int] aa2;
     assert(0 !in aa2);
     modifyNoRef(aa2);
     assert(0 in aa2);

     int[int] aa3;
     const key = aa3.uniqueKey;
     assert(key in aa3); // <--
}

```

The `key in aa3` assert fails unless I make `uniqueKey` take its 
argument by ref. But `modifyNoRef` manages just fine without it. 
They work on the same type and they're all templates. The AAs 
they are passed have not been assigned any prior values.

What is the deciding difference between those two functions?


More information about the Digitalmars-d-learn mailing list