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() {

}

Reply via email to