On Thursday, 6 October 2016 at 02:09:44 UTC, Adam D. Ruppe wrote:
On Thursday, 6 October 2016 at 01:23:35 UTC, Patric Dexheimer
wrote:
Why?
Because you'd be overwriting that immutable member. Structs
just put structure around their contents, but it doesn't change
their nature. That struct is no different than if you wrote
`immutable size_t` as the value - and of course, overwriting
that; changing that violates that promise that you won't change
it.
You could store pointers to those structs though, and overwrite
the pointer.
Hm... so is there any way around this?
In my case I have a RandomAccessRange which caches it's results.
Reduced example:
struct Res
{
immutable int i;
}
struct Range
{
Res[size_t] c;
Res fun(size_t i)
{
if (auto p = i in c)
return *p;
else
{
c[3] = Res(3); /// ERROR line 26
return c[3];
}
}
}
unittest
{
auto r = Range();
r.fun(3);
}
which errors at compilation with
onlineapp.d(26): Error: cannot modify struct this.c[3] Res with
immutable members
A workaround I thought could be to use an array
struct Range
{
//Res[size_t] c;
struct Con { Res c; bool valid; }
Con[] c;
Res fun(size_t i)
{
if (c.length > i && c[i].valid)
return c[i].c;
else
{
if (c.length <= i) c.length = i + 1;
auto r = Con(Res(3), true);
c[i] = r; /// same ERROR!
return c[i].c;
}
}
}
However, of course this also fails because randomly assigning the
array elements will overwrite it. So the associative array seems
like the better idea. However, not being able to INITIALIZE an
assoc array element disallows its usage.
Is there any solution, trick or workaround??