tail const
Steven Schveighoffer
schveiguy at yahoo.com
Fri Dec 3 18:02:10 PST 2010
On Fri, 03 Dec 2010 20:40:23 -0500, Michel Fortin
<michel.fortin at michelf.com> wrote:
>
> A fine explanation. Thank you.
>
> I disagree about your proposed solution, but I recognize the problem.
> The basic problem with your solution is that it creates a new kind of
> const, a new kind of immutable and a new kind of shared. You should
> realize that for the compiler to know the constness of member variables
> inside a function, it'll have to know whether the 'this' pointer is
> 'const' or 'tail const'. So I think it's the wrong path.
Yes, Andrei also pointed out this problem. Part of the issue is that
member functions are always passed 'this' by ref. Arrays don't have this
problem because you have control over passing them by ref or by value. I
agree my solution does not work, or actually that it works but makes
things worse :)
>
> The right path would be, I think, to parametrize the constness in the
> type. A way to do this within the current constrains of the language
> would be to make Range implicitly convertible to ConstRange, something
> you should be able to do with "alias X this", X being a function
> returning a ConstRange. The disadvantages are the duplication of the
> opSlice function, and the inability to cast implicitly a ref Range to
> ref ConstRange or a Range[] to a ConstRange[].
In fact, I'm not sure you could do Range[] to ConstRange[], I think that's
two levels of indirection.
I can sort of live with defining multiple functions, at least it would be
possible to make something work.
If we could have some way to hook inout, like designate Range for mutable,
ConstRange for const, and ImmutableRange for immutable, and let InoutRange
represent the inout type (which gets implicitly converted to one of those )
But maybe I'm dreaming :)
> I have an idea that would fix those: make a template struct/class
> instance implicitly convertible to another instance of that same
> template if all members share the same memory layout and each member is
> implicitly convertible to the same member of the other template.
I had thought of that too, a long time ago, but I wasn't sure if it could
work. I'd go two steps further:
1. all the member variable names must be identical.
2. you need to identify that implicit conversion is allowed.
1 is for sanity ;)
struct Pair(T)
{
T x;
T y;
}
struct ConstPair(T)
{
const(T) y;
const(T) x;
}
2 is to ensure you are not able to incorrectly morph data into things it
should not be. i.e.:
struct Point
{
int x;
int y;
}
I don't think you should be able to implicitly cast Pair!int to Point,
sometimes you want to define different APIs for the same data.
-Steve
More information about the Digitalmars-d
mailing list