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

Reply via email to