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