Is there a way to disable copying of an alias this'd member? - trying to make a NotNull type

aliak something at something.com
Fri May 24 11:40:20 UTC 2019


On Friday, 24 May 2019 at 10:40:01 UTC, Simen Kjærås wrote:
> On Friday, 24 May 2019 at 10:16:50 UTC, aliak wrote:
>> Basically, I want this to fail:
>>
>> auto notNull(T, Args...)(Args args) {
>>     return NotNull!T(new T(args));
>> }
>>
>> struct NotNull(T) {
>>   private T _value;
>>   @property ref inout(T) value() inout { return this._value; }
>>   alias value this;
>>   //disable opAssign to null as well
>> }
>>
>> class C {}
>> void func(ref C t) {
>>   t = null;
>> }
>>
>> auto a = notNull!C;
>> func(a); // i want a compile error here
>>
>> Any ideas that don't involve disabling copying or making the 
>> property non-ref?
>
> Pretty sure that can't be done. On the other hand, why is the 
> property ref if you're explicitly not going to use its 
> ref-ness? Alternatively, can you show me how you use its 
> ref-ness?

It's ref so that you can do this for e.g.

class C { int i; }
auto a = notNull!C;
a.i = 3;

I guess maybe there's a way to go about supporting that kinda 
thing with opDispatch. But I've tried doing that in the optional 
type [0] and it's rather painful to get right, and trickier to 
make @safe as well.

>
> And just for completeness, you are aware that alias this takes 
> an overload set, so that this works?
>
>    struct NotNull(T) {
>        private T _value;
>        @property inout(T) value() inout { return _value; }
>        @property void value(T val) { _value = val; } // new
>        alias value this;
>        // disable opAssign to null as well
>    }
>
>    class C {}
>    void func(ref C t) { t = null; }
>
>    unittest {
>        NotNull n;
>        n = new C(); // Look ma, I'm assigning without ref!
>        func(n); // Does not compile - value() doesn't return by 
> ref
>    }
>
> --
>   Simen

Si si. I is aware. I've disabled opAssign to T actually (i think 
i have at least). And I only allow assigning to another NotNull 
else there's no way to guarantee that the NotNull stays non null.

It looks like I'm going to have to sacrifice being able to 
manipulate member variables of the type the NotNull is wrapping, 
or give up on the guarantee of the inner value not being null.

[0] https://code.dlang.org/packages/optional



More information about the Digitalmars-d-learn mailing list