Hmm - about manifest/enum

Steven Schveighoffer schveiguy at yahoo.com
Wed Jan 2 05:13:40 PST 2008


"Walter Bright" wrote
> Bill Baxter wrote:
>> What was the fundamental problem with creating some syntax that would let 
>> you peel the reference part off a class reference?
>
> const(C)&[] a;
>
> is a sortable array of constant C's. But what is:
>
> const(int)&[] a;

A sortable array of int references.  If references are to be consistent, the 
meaning of an int reference is that it acts like an int until you assign to 
another int reference.  If you assign it to another int reference, then type 
now references the same thing as the new int reference.  If you assign it to 
another int, that is a compiler error (can't assign a non reference value to 
a reference just like you can't assign a non pointer value to a pointer).

>
> Is it sortable or not? If it is sortable, then & means "tail const". If it 
> is not sortable, then how, in generic code, do we specify a sortable array 
> of type T?

You are missing the point.  & does not mean tail const.

const(int)*[] a;

This is an array of int pointers that are TAIL CONST.  This does not mean * 
is tail const, does it?

& means 'a reference to', just like * means 'a pointer to'.

There is no ambiguity, no inconsistency, no violation of const rules.

>
> const(T)&[] a; // is it sortable or not?
>
> Now, if & is to mean "tail const", what do we do with:
>
> struct S
> { int i;
>   int* p;
>   void foo() { *p = 3; }
> }
>
> const(S)& s;
>
> Does that mean we can modify the members of S, but not what those members 
> may point to? How do we specify that member function foo is "tail const" ?

Nope, it means you cannot modify members of S and you cannot call foo 
because it is not const.  const(S)& is a mutable reference to a const S just 
like const(S)* is a mutable pointer to a const S.

>
> And what do we do with:
>
> struct S { C c; }
> const(S)&[] a;
>
> Here, we've wrapped a class with a struct. Is it possible to make S behave 
> like its underlying C? If not, we don't have general purpose UDTs. We have 
> a heaping pile of special cases.

Why wouldn't you be able to?  The only overload that you cannot change is 
the assignment to another S reference.  You can overload assign to a C, 
because it is not a reference to an S.  In this case however, since S is 
const, you cannot assign to another C, just like you wouldn't be able to 
assign a C to a const(C).

You may look at this whole post and think "ok, & is just like *, why even 
have &?", well, the point is, for classes, & is a reference to the class 
data, not a reference to a class reference.  So for a class C, C& x is 
equivalent to C x.  The thing & gets us is a way to specify universally 
'reference to'.  This would actually be very beneficial to generic 
programming.

There is one other possibility that you have not (at least publicly) 
considered, which I outlined in my post on 12/7 titled "The problem with 
const (and a solution)":

const(*C)*[] array;

This would be an array of mutable class references.  Having this possibility 
gives us at least a way to specify tail-const class references.  This 
solution has the benefit of not introducing references to other types (which 
would be a lot of work for you).  My preference is to have the reference 
operator, & if possible, but the *C solution is at least workable.

One further thing.  If you could at least pledge to have a way to specify a 
tail-const class reference before 2.0 is officially released, I would be 
willing to accept that for now.  I understand that adding something like the 
reference operator would be a lot of extra work besides the const stuff, so 
I would understand if you did your current const proposal with the intent of 
doing the reference work later.

-Steve 





More information about the Digitalmars-d mailing list