const again
Christopher Wright
dhasenan at gmail.com
Thu Dec 6 14:46:55 PST 2007
Walter Bright wrote:
> TailConst!(C)[] a;
> which would do whatever was necessary under the hood to allow the
> elements of a to be rebound while still keeping the contents of the C
> objects const.
The TailConst template would probably need to be a struct:
struct TailConst (T) {
static if (is (T == class) || is (T == interface)) {
// can just store a reference
} else {
// assignment mallocs some memory and copies arg onto heap
// store a ptr
}
}
And then we'd need an opDot if we wanted transparent access. It's an
annoyance, but a minor one, to have to use opDeref.
But I think perhaps the problem with arrays is that there's no way to
say the array is not const, but its members are. The obvious syntax
would be:
const(Foo)[] foos = new const(Foo)[5];
foos[2] = new Foo(); // ok
const(Foo[]) cfoos = new Foo[5];
cfoos[3] = new Foo(); // error; cfoos is const
Then string would be an alias to invariant(char[]) rather than
invariant(char)[], which makes sense. It's not a mutable array of
invariant characters.
However, this would suggest:
const(const(Foo)[]) ccfoos;
Which would suggest the cfoos array is a const buffer, but if it holds
reference types, they are not const. And if the array is const, you
can't rebind its elements.
The solution to that mess, if you need transitive const, is to define
const(T[]) to be the same as const(const(T)[]), which won't affect
primitives and value types but will get the desired result for reference
types.
But it doesn't make sense to consider an array const if its elements are
const; that would be extremely annoying with templates. If you wanted to
use arrays for anything nontrivial, you'd have to start it with:
static if (is (T == const)) {
alias TailConst!(T) ElemType;
} else {
alias T ElemType;
}
More information about the Digitalmars-d
mailing list