How to get an inout constructor working with a template wrapper

Steven Schveighoffer schveiguy at gmail.com
Sun Jul 29 12:45:48 UTC 2018


On 7/28/18 6:09 PM, aliak wrote:
> On Friday, 27 July 2018 at 14:38:27 UTC, Steven Schveighoffer wrote:
>> On 7/27/18 9:29 AM, aliak wrote:
>>> 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!
>>
>> And instantiate a new template for all mutabilities. Whereas inout 
>> would only instantiate one (and disallows modification of val if not 
>> const or immutable).
>>
>> -Steve
> 
> If you change the ctor to be inout then you get (from the link above):
> 
> onlineapp.d(4): Error: cannot implicitly convert expression val of type 
> onlineapp.C to inout(C)
> onlineapp.d(28): Error: template instance `onlineapp.W!(C).W.__ctor!(C)` 
> error instantiating
> onlineapp.d(4): Error: cannot implicitly convert expression val of type 
> S1 to inout(S1)
> onlineapp.d(44): Error: template instance 
> `onlineapp.W!(S1).W.__ctor!(S1)` error instantiating
> onlineapp.d(4): Error: cannot implicitly convert expression val of type 
> onlineapp.C to inout(C)
> onlineapp.d(9): Error: template instance `onlineapp.W!(C).W.__ctor!(C)` 
> error instantiating
> onlineapp.d(52):        instantiated from here: wrap!(C)
> onlineapp.d(4): Error: cannot implicitly convert expression val of type 
> const(C) to inout(const(C))
> onlineapp.d(9): Error: template instance 
> `onlineapp.W!(const(C)).W.__ctor!(const(C))` error instantiating
> onlineapp.d(53):        instantiated from here: wrap!(const(C))
> 
> Am I applying inout incorrectly?

No, you need to apply it to wrap as well. I can't get run.dlang.io to 
work for posting a link, so here is my modified version:

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

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

class C {}
struct S0 {}
struct S1 { C c; }

void f_dprimitive() {
     int a = 3;
     const int b = 3;
     immutable int c = 3;
     const int d = a;
     immutable int e = a;

     auto sc = wrap(const(int)(3));      // note the modifications here
     auto si = wrap(immutable(int)(3));
}

void f_class() {
     W!C a = new C();
     const W!C b = new C();
     immutable W!C c = new immutable C();
     const W!C d = a;

     //immutable W!C e = a; // cannot implicitly convert mutable to 
immutable
}

void f_struct() {
     W!S0 a = S0();
     const W!S0 b = S0();
     immutable W!S0 c = S0();
     const W!S0 d = a;
     immutable W!S0 e = a;
}

void f_struct_with_indirection() {
     W!S1 a = S1();
     const W!S1 b = S1();
     immutable W!S1 c = immutable S1();
     const W!S1 d = a;
//    immutable W!S1 e = a; // cannot implicitly convert mutable to 
immutable
}

void f_wrapper() {
     auto a = wrap(new C);
     auto b = wrap(new const C);
     auto c = wrap(new immutable C);
     const W!C d = a;
//    immutable W!C e = a; // cannot implicitly convert mutable to immutable
}

void f_wrapper2() {
     Object ma = new C();
     Object ca = new const C();
     Object ia = new immutable C();

     auto a = wrap(cast(C)ma);
     auto b = wrap(cast(const C)ma);
     auto c = wrap(cast(immutable C)ma);
}

void main() {

}


More information about the Digitalmars-d-learn mailing list