tail const

Steven Schveighoffer schveiguy at yahoo.com
Sat Dec 4 20:17:37 PST 2010


On Sat, 04 Dec 2010 08:55:19 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 12/4/10 1:48 AM, Dmitry Olshansky wrote:
>> On 04.12.2010 6:23, Andrei Alexandrescu wrote:
>>> On 12/3/10 7:40 PM, Michel Fortin wrote:
>>>> 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'm afraid that can't work.
>>>
>>> struct A(T) {
>>> T obj;
>>> void fun() { obj->method(); }
>>> }
>>>
>>
>> Looks discouraging at first, but perfectly valid given that the example
>> works only when A!Object compiles, i.e. Object have method 'method', and
>> then:
>>
>>> auto a = new A!Widget;
>>> a.obj = new Widget;
>>> A!Object b = *a; // works because Widget converts to Object
>> // A!Object* b = a; // should not compile, and would be a problem if A
>> is a class
>> //now we have another struct b with reference to a's widget
>>> b.obj = new Object; //no problem, a stays intact
>>> b.fun(); // since A!Object already compiles, it's perfectly valid
>>
>> In fact, it looks like Michel's rule is very promising, just replace
>> "struct/class" part with "struct" in definition.
>
> If conversion is allowed only for values (i.e. perform a memberwise copy  
> of one struct to another), it looks like things could work. Almost. The  
> problem is that that surreptitious copy completely bypasses the  
> constructor:
>
> struct A(T) {
>      private T obj;
>      private bool isObject;
>      this(T obj_) {
>          obj = obj_;
>          static if (is(T == Object)) isObject = true;
>      }
> }

These are the kinds of things I am afraid of with static if.  Because we  
can change the behavior it is not safe to assume that we can simply copy  
or do a reinterpret-cast.  I like the idea, but I think we need some sort  
of way to limit the scope of this feature.  Can we define a new way to  
just template constancy?  The compiler and programmer can easily reason  
about that.

Now, you can just replace isObject with isConst, and we have the same  
issue if constancy is allowed to be templated.  This is kind of why I  
didn't want to rely on templates to do tail-const -- there is just too  
much power there.

Perhaps we can limit compile-time checking of this new const template  
parameter.  If the compiler detects any static check on the const  
parameter, it doesn't allow implicit casting.  Is that feasible?

-Steve


More information about the Digitalmars-d mailing list