Getting the const-correctness of Object sorted once and for all
Era Scarecrow
rtcvb32 at yahoo.com
Mon May 14 14:30:55 PDT 2012
On Monday, 14 May 2012 at 19:24:15 UTC, Steven Schveighoffer
wrote:
> I have never seen this suggested before. I would guess that it
> might be considered a bug, since you are accessing the outer
> instance via a pointer contained in the inner instance.
>
> But I like the approach (even if it is a bug)!
I was thinking something along these lines last night, although
I couldn't put it quite together, it did end up using alias this.
I forget but someone commented on possibly using a flag that
would let you write to a variable for the first time, and break
if you tried to read from it. A thought that went through my head
would indeed need a little thought, but I couldn't see an easy
way to do it outside of a new keyword. What if .init (or null)
was your flag effectively? Let's assume allowinit (or something
better) to be the keyword. Then...
struct S {
allowinit uint hash;
uint toHash() const {
if (hash == uint.init) { //read always allowed safely within
struct
hash = 1;
}
return hash;
}
void throwtest() {
hash = 2; //might not throw
}
}
func(){
const S s, z;
// writeln(s.hash); //throw!
//throwtest(); //would not throw here
writeln(z.toHash()); //fine
writeln(z.toHash()); //yep still fine
writeln(z.hash); //allowed? technically yes...
throwtest(); //throw!
}
Course these types may cause more problems if outside code had
to do extra checks, so making allowinit forced to be private
would remove that issue leaving it only to within the struct,
making it good for caching results as you could only set it once.
But that only works with const data, immutable being locked in
memory it wouldn't do the job. So the only way to get around that
is to allow a constructor that sets it during construction.
//as above
struct S {
this(uint h) {
hash = h;
}
}
func(){
immutable S i; //compile error! Immutable cannot have allowinit
with default constructor!
immutable S i2 = S(10); //fine
immutable S i2 = S(uint.init); //error! allowinit cannot be
assigned to .init value for immutable!
}
More information about the Digitalmars-d
mailing list