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;
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?