How to get an inout constructor working with a template wrapper

aliak something at something.com
Fri Jul 27 13:29:29 UTC 2018


On Monday, 23 July 2018 at 14:46:32 UTC, Timoses wrote:
> On Monday, 23 July 2018 at 12:02:58 UTC, aliak wrote:
>> [...]
>
> Both of these seem to work (as you pointed out)
>
>     // immutable(W!int)
>     auto si = wrap!(int)(cast(immutable)3); // or 
> wrap(cast(immutable)3);
>     // W!(immutable(int))
>     auto si2 = W!(immutable int)(3);
>
>> [...]
>
> I don't know why
>
>     wrap!(immutable int)(3);
>
> is not working. The error message
>
>     "Error: inout on return means inout must be on a parameter 
> as well for pure nothrow @nogc @safe 
> inout(W!(immutable(int)))(return immutable(int) t)"
>
> sounds very odd and not at all helpful, at least regarding that 
> removing immutable from the template argument works.
>
>> [...]
>
> The depths of D. Why does the following only work with "return 
> ref"?
>
>     struct W(T) {
>         T val;
>         this(U : T)(auto ref inout U val) inout {
>             pragma(msg, typeof(val));
>             this.val = val;
>         }
>     }
>
>     // Fails without "return ref" (escaping t warning...)
>     auto wrap(T)(return ref inout T t) {
>         return inout W!T(t);
>     }
>
>     class C {}
>
>     void main() {
>         immutable C ci = new immutable C;
>         auto i = wrap(im);
>         pragma(msg, typeof(i));
>     }

Ok, thanks to Simen from another post [0], I just figured out 
what the correct constructor and factory method for a template 
wrapper should be:

https://run.dlang.io/is/S4vHzL

struct W(T) {
     T val;
     this(U : T, this This)(auto ref U val) {
         this.val = val;
     }
}

auto wrap(T)(auto ref T t) {
     return W!T(t);
}

Seems to catch all cases!

[0]: 
https://forum.dlang.org/thread/hxbeektmpnmfdbvjrtcf@forum.dlang.org


More information about the Digitalmars-d-learn mailing list