const again
Steven Schveighoffer
schveiguy at yahoo.com
Thu Dec 6 16:30:15 PST 2007
"Walter Bright" wrote
> Janice Caron wrote:
>> I understand the problem. Have you considered the possible solution
>> which has been suggested on this group - a special syntax for classes
>> having mutable refs to constant data? Under that suggestion, the above
>> code would become:
>>
>> class C { }
>> const(C)&[] a;
>> a[3] = new C(); // OK
>>
>> It's the ampersand that makes it OK. It tells you that the reference
>> is not constified.
>>
>> I think that would work, in exactly the same way that
>>
>> struct S { }
>> struct(S)*[] a;
>> a[3] = new S(); // OK
>>
>> works.
>
> There are a couple problems with it, the worst of which is its impact on
> generic code:
> const(T)[]
> Would you put the & there or not? What would & mean if one wrote:
> struct S { C c; }
> const(S)&[] a;
> ?
What happens if you have this?
const(T)*[]
If T is a struct, then it's fine, but if it's a class, then what? To me the
situation is just as bad.
This whole problem stems from the fact that a struct declaration is a value
type and a class declaration is a reference type, but they look the same.
You are never going to have a consistent syntax for generic const code
because you don't have a consistent syntax for normal declarations.
I see one good solution. A pointer/reference declarator that acts the same
for both structs and classes.
class C {}
struct S {}
C x; // a reference to a class
S x; // a struct
C& x; // a reference to a class (identical to C x)
S& x; // a reference to a struct (identical to S * x)
S& x = new S; // heap allocated struct
C& x = new C; // heap allocated class
const(C) x; // a const reference to a const C
const C x; // identical to const(C)
const(C)& x; // a mutable reference to a const C
const(C)[] x; // an array of const references to const C instances
const(C)&[] x; // an array of mutable references to const C instances
const(S) x; // a const S. Cannot set x or x.member
const S x; // identical to const(S)
const(S)[] x; // an array of const S types
const(S)*[] x; // an array of mutable references to const S types
const(S)&[] x; // an array of mutable references to const S types (identical
to const(S)*[])
you need generic tail-const code? use const(T)&
you need generic fully-const code? use const(T)
or use something else instead of &, I don't care. It just seems like this
notion that I can now have tail-const structs, but not tail-const classes is
just as bad, if not worse, than the original problem.
> One principle we try to adhere to is that it should make sense to be able
> to wrap any type with a struct, and have it be possible for that struct to
> behave as if it were that member type.
const (X)* m;
Please tell me how you will replace m with a 'smart' pointer type that is
mutable, but the pointer contents are not. Without using a template.
Because using a Template, I can do it with my regime also :)
> And finally, this suggests that & means "tail-const". Tail-const has that
> severe problem that there is no such thing as a tail-const member function
> (i.e. a member function that can modify the fields of the object, but not
> anything those fields refer to).
Huh? I thought tail-const was that you could change the reference but not
the members? i.e. const(S)* x, I can change x but not x.member?
-Steve
More information about the Digitalmars-d
mailing list