Re: How to get an inout constructor working with a template wrapper

2018-07-31 Thread aliak via Digitalmars-d-learn
On Tuesday, 31 July 2018 at 21:54:54 UTC, Steven Schveighoffer 
wrote:
Because inout is trying to combine all mutability modifiers 
into one. You want to specify the type, not the mutability, in 
the template parameter T.


Ahhh. Ok I see... I think.


This doesn't make sense. Can you post runnable code?


Hehe, ok, so I fell victim to compiler generating an error for 
number 3 and then nothing else :p But yes you're right, if I 
comment out number 3 then 6 errors as well. Sorry my bad!




When I go back to your original failing example, and replace 
the 3 with immutable(int)(3), it still fails.




So for 3, compiler sees the instantiation:

  inout(W!(immutable int)) wrap(immutable(int))

If I understood you correctly?


Yes. You can see for yourself with pragma msg:

pragma(msg, typeof(t)); // immutable(int)



But then what does it see in number 6, which works fine?


I'm skeptical this is the case.

Note that you may only see the instantiation error ONCE.


Yep, you nailed that one.




And why is 2 ok if 3 is not?


because inout(const(T)) cannot have its inout removed.


Because it may be an immutable? Or?

But the complaint is really the issue. Clearly inout is 
specified, so it shouldn't complain that it isn't.


Aye. I guess that's right.



-Steve





Re: How to get an inout constructor working with a template wrapper

2018-07-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/31/18 5:29 PM, aliak wrote:

On Tuesday, 31 July 2018 at 12:37:34 UTC, Steven Schveighoffer wrote:

On 7/29/18 1:46 PM, aliak wrote:

On Sunday, 29 July 2018 at 12:45:48 UTC, Steven Schveighoffer wrote:


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:




Ah bugger, right!

Ok so there's no way to make explicit instantiation involving 
immutable work in the face of an inout parameter? Seems rather 
inconsistent no?


It's not that there's no way, the issue is simply that you are 
explicitly instantiating incorrectly.


wrap!int(immutable(int)(3));



Ok bear with me, but I'm really confused why 
"wrap!int(immutable(int)(3))" is "correct".


Because inout is trying to combine all mutability modifiers into one. 
You want to specify the type, not the mutability, in the template 
parameter T.


Essentially, if this were a normal function that takes only ints, you 
would write it once for all mutabilities:


auto wrap(inout(int) x)

Which works for mutable, const, or immutable int.



This all seems very inconsistent:

1. wrap!(int)(3); // ok
2. wrap!(const int)(3); // ok
3. wrap!(immutable int)(3); // nope
4. wrap!(int)(3); // ok
5. wrap!(const int)(const(int)(3)); // ok
6. wrap!(immutable int)(immutable(int)(3)); // ok!


This doesn't make sense. Can you post runnable code?

When I go back to your original failing example, and replace the 3 with 
immutable(int)(3), it still fails.




So for 3, compiler sees the instantiation:

  inout(W!(immutable int)) wrap(immutable(int))

If I understood you correctly?


Yes. You can see for yourself with pragma msg:

pragma(msg, typeof(t)); // immutable(int)



But then what does it see in number 6, which works fine?


I'm skeptical this is the case.

Note that you may only see the instantiation error ONCE.

And why is 2 ok 
if 3 is not?


because inout(const(T)) cannot have its inout removed.

And finally, why can't the compiler leave the inout there 
and then it doesn't need to complain about it?
It has to strip inout to be consistent -- we want canonical types. It's 
the same reason immutable(const(int)) is just immutable(int), and 
const(const(const(int))) is just const(int). Having the original types 
be left in place would make for some weird rules.


But the complaint is really the issue. Clearly inout is specified, so it 
shouldn't complain that it isn't.


-Steve


Re: How to get an inout constructor working with a template wrapper

2018-07-31 Thread aliak via Digitalmars-d-learn
On Tuesday, 31 July 2018 at 12:37:34 UTC, Steven Schveighoffer 
wrote:

On 7/29/18 1:46 PM, aliak wrote:
On Sunday, 29 July 2018 at 12:45:48 UTC, Steven Schveighoffer 
wrote:


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:




Ah bugger, right!

Ok so there's no way to make explicit instantiation involving 
immutable work in the face of an inout parameter? Seems rather 
inconsistent no?


It's not that there's no way, the issue is simply that you are 
explicitly instantiating incorrectly.


wrap!int(immutable(int)(3));

-Steve


Ok bear with me, but I'm really confused why 
"wrap!int(immutable(int)(3))" is "correct".


This all seems very inconsistent:

1. wrap!(int)(3); // ok
2. wrap!(const int)(3); // ok
3. wrap!(immutable int)(3); // nope
4. wrap!(int)(3); // ok
5. wrap!(const int)(const(int)(3)); // ok
6. wrap!(immutable int)(immutable(int)(3)); // ok!

So for 3, compiler sees the instantiation:

 inout(W!(immutable int)) wrap(immutable(int))

If I understood you correctly?

But then what does it see in number 6, which works fine? And why 
is 2 ok if 3 is not? And finally, why can't the compiler leave 
the inout there and then it doesn't need to complain about it?


Cheers,
- Ali


Re: How to get an inout constructor working with a template wrapper

2018-07-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/29/18 1:46 PM, aliak wrote:

On Sunday, 29 July 2018 at 12:45:48 UTC, Steven Schveighoffer wrote:


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:




Ah bugger, right!

Ok so there's no way to make explicit instantiation involving immutable 
work in the face of an inout parameter? Seems rather inconsistent no?


It's not that there's no way, the issue is simply that you are 
explicitly instantiating incorrectly.


wrap!int(immutable(int)(3));

-Steve


Re: How to get an inout constructor working with a template wrapper

2018-07-29 Thread aliak via Digitalmars-d-learn
On Sunday, 29 July 2018 at 12:45:48 UTC, Steven Schveighoffer 
wrote:


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:




Ah bugger, right!

Ok so there's no way to make explicit instantiation involving 
immutable work in the face of an inout parameter? Seems rather 
inconsistent no?


https://issues.dlang.org/show_bug.cgi?id=19126

Thanks,
- Ali


Re: How to get an inout constructor working with a template wrapper

2018-07-29 Thread Steven Schveighoffer via Digitalmars-d-learn

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

}


Re: How to get an inout constructor working with a template wrapper

2018-07-28 Thread aliak via Digitalmars-d-learn
On Friday, 27 July 2018 at 14:34:54 UTC, Steven Schveighoffer 
wrote:
The problem here is that inout(immutable(int)) is equivalent to 
immutable(int).


That is, all flavors of mutability are equivalent to 
immutable(int):


/*mutable*/(immutable(int)) => immutable(int)
  const(immutable(int)) => immutable(int)
  immutable(immutable(int)) => immutable(int)

So the compiler really looks at your wrap instantiation like 
this;


inout(W!(immutable(int))) wrap(immutable(int) t)


Ah ok, so the compiler remove inout behind me back here? (And 
then tells me it needs to be there? :p)




which triggers the (really bad) message.

I'd ask, why are you even worrying about explicit 
instantiation? Why not just wrap(3)?


Just because I don't see why it should not work really. Why not 
allow wrap!(immutable int)(3)?




or (if you really want to test it) wrap(immutable(int)(3))?



To make it compile successfully you can either:

1) Chance immutable to const, then it works for some reason.


Because immutable(const(int)) => immutable(int), so the 
compiler can't remove the inout behind your back.


2) Change the line to: "auto si = wrap(cast(immutable int)3);" 
- i.e. do not explicitly provide type information.


Yep, do this :)

Note that the point of inout is 2-fold:

1. reduce template instantiations. In fact, wrap!int works for 
const, mutable and immutable int.
2. ENSURE that the data isn't modified, even in the case of 
mutable parameters.


Thanks for the explanations! For some reason it's hard to get it 
all to *just work* right now without the template this. But it's 
probably some minor detail I'm just overlooking...




-Steve





Re: How to get an inout constructor working with a template wrapper

2018-07-28 Thread aliak via Digitalmars-d-learn
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?


Re: How to get an inout constructor working with a template wrapper

2018-07-27 Thread Steven Schveighoffer via Digitalmars-d-learn

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


Re: How to get an inout constructor working with a template wrapper

2018-07-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/23/18 8:02 AM, aliak wrote:

On Sunday, 22 July 2018 at 23:11:09 UTC, Ali Çehreli wrote:
Without much confidence on my side, first, I think you need to make 
the constructor parameter inout(T) as well. Otherwise, you may be 
making a const(W!T) initialized with a non-const T.


After that, I like the "type constructor" syntax in main_alt() below 
(which works) but a better approach is to use a convenience function 
like wrap() below:


struct W(T) {
    T val;
    this(inout(T) val) inout {
    this.val = val;
    }
}

class C {}

void main_alt() {
    auto a = W!C(new C);
    auto b = immutable W!(immutable C)(new C);
}

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

void main() {
    auto a = wrap(new C);
    auto b = wrap(new immutable(C));
}

Ali
"taklitlerinden sakınınız" :o)


Thank you Ali! That helped :) I've gotten most of it sorted out now, and 
the factory wrap is definitely the way to go, it also turned out that 
inout(T) and inout T (so inout without parens) was surprisingly 
different (maybe it's a bug? - to test you can remove the parens around 
U on line 3 in this sample: https://run.dlang.io/is/gd5oxW


This seems like a bug to me.

The semantic difference is that inout(U) means the TYPE inout(U), 
whereas inout U means the variable U has the STORAGE CLASS inout, which 
also happens to make it an inout(U) type. As far as I know, the storage 
class inout shouldn't have any other effect on the semantic meaning.


I can't imagine any difference there, but it appears to not recognize 
that return should be inferred? I don't know.



Also over there, line 24:

auto si = wrap!(immutable int)(3);

seems to be giving problems. Any ideas there? Error is:

onlineapp.d(8): Error: inout on return means inout must be on a 
parameter as well for pure nothrow @nogc @safe 
inout(W!(immutable(int)))(immutable(int) t)
onlineapp.d(23): Error: template instance 
`onlineapp.wrap!(immutable(int))` error instantiating


The problem here is that inout(immutable(int)) is equivalent to 
immutable(int).


That is, all flavors of mutability are equivalent to immutable(int):

/*mutable*/(immutable(int)) => immutable(int)
  const(immutable(int)) => immutable(int)
  immutable(immutable(int)) => immutable(int)

So the compiler really looks at your wrap instantiation like this;

inout(W!(immutable(int))) wrap(immutable(int) t)

which triggers the (really bad) message.

I'd ask, why are you even worrying about explicit instantiation? Why not 
just wrap(3)?


or (if you really want to test it) wrap(immutable(int)(3))?



To make it compile successfully you can either:

1) Chance immutable to const, then it works for some reason.


Because immutable(const(int)) => immutable(int), so the compiler can't 
remove the inout behind your back.


2) Change the line to: "auto si = wrap(cast(immutable int)3);" - i.e. do 
not explicitly provide type information.


Yep, do this :)

Note that the point of inout is 2-fold:

1. reduce template instantiations. In fact, wrap!int works for const, 
mutable and immutable int.
2. ENSURE that the data isn't modified, even in the case of mutable 
parameters.


-Steve


Re: How to get an inout constructor working with a template wrapper

2018-07-27 Thread aliak via Digitalmars-d-learn

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/hxbeektmpnmfdbvjr...@forum.dlang.org


Re: How to get an inout constructor working with a template wrapper

2018-07-23 Thread Timoses via Digitalmars-d-learn

On Monday, 23 July 2018 at 12:02:58 UTC, aliak wrote:


Thank you Ali! That helped :) I've gotten most of it sorted out 
now, and the factory wrap is definitely the way to go, it also 
turned out that inout(T) and inout T (so inout without parens) 
was surprisingly different (maybe it's a bug? - to test you can 
remove the parens around U on line 3 in this sample: 
https://run.dlang.io/is/gd5oxW


Also over there, line 24:

auto si = wrap!(immutable int)(3);


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);



seems to be giving problems. Any ideas there? Error is:

onlineapp.d(8): Error: inout on return means inout must be on a 
parameter as well for pure nothrow @nogc @safe 
inout(W!(immutable(int)))(immutable(int) t)
onlineapp.d(23): Error: template instance 
`onlineapp.wrap!(immutable(int))` error instantiating


To make it compile successfully you can either:

1) Chance immutable to const, then it works for some reason.
2) Change the line to: "auto si = wrap(cast(immutable int)3);" 
- i.e. do not explicitly provide type information.


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.




Cheers,
- Ali


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));
}


Re: How to get an inout constructor working with a template wrapper

2018-07-23 Thread aliak via Digitalmars-d-learn

On Monday, 23 July 2018 at 12:02:58 UTC, aliak wrote:

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


Sorry wrong link!

This one is correct -> https://run.dlang.io/is/azxmGN


Re: How to get an inout constructor working with a template wrapper

2018-07-23 Thread aliak via Digitalmars-d-learn

On Sunday, 22 July 2018 at 23:11:09 UTC, Ali Çehreli wrote:
Without much confidence on my side, first, I think you need to 
make the constructor parameter inout(T) as well. Otherwise, you 
may be making a const(W!T) initialized with a non-const T.


After that, I like the "type constructor" syntax in main_alt() 
below (which works) but a better approach is to use a 
convenience function like wrap() below:


struct W(T) {
T val;
this(inout(T) val) inout {
this.val = val;
}
}

class C {}

void main_alt() {
auto a = W!C(new C);
auto b = immutable W!(immutable C)(new C);
}

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

void main() {
auto a = wrap(new C);
auto b = wrap(new immutable(C));
}

Ali
"taklitlerinden sakınınız" :o)


Thank you Ali! That helped :) I've gotten most of it sorted out 
now, and the factory wrap is definitely the way to go, it also 
turned out that inout(T) and inout T (so inout without parens) 
was surprisingly different (maybe it's a bug? - to test you can 
remove the parens around U on line 3 in this sample: 
https://run.dlang.io/is/gd5oxW


Also over there, line 24:

auto si = wrap!(immutable int)(3);

seems to be giving problems. Any ideas there? Error is:

onlineapp.d(8): Error: inout on return means inout must be on a 
parameter as well for pure nothrow @nogc @safe 
inout(W!(immutable(int)))(immutable(int) t)
onlineapp.d(23): Error: template instance 
`onlineapp.wrap!(immutable(int))` error instantiating


To make it compile successfully you can either:

1) Chance immutable to const, then it works for some reason.
2) Change the line to: "auto si = wrap(cast(immutable int)3);" - 
i.e. do not explicitly provide type information.


Cheers,
- Ali



Re: How to get an inout constructor working with a template wrapper

2018-07-22 Thread Ali Çehreli via Digitalmars-d-learn

On 07/22/2018 03:51 PM, aliak wrote:
> Hi,
>
> In the code below:
>
> struct W(T) {
>  T val;
>  this(T val) inout {
>  this.val = val;
>  }
> }
>
> class C {}
>
> void main() {
> W!C a = new C;
> immutable W!C b = new C;
> }
>
> W!C a = new C results in: "Error: cannot implicitly convert expression
> val of type C to inout(C)."
>
> If I remove the inout on the constructor then the error is on the other
> line and is: "Error: mutable method W!(C).W.this is not callable using a
> immutable object"
>
> If the class is changed to a struct through,  then the constructor with
> inout works on both lines in main above.
>
> So I guess this has something to do with reference types (As the same
> behaviour is exhibited if T == int*) What's the recommended way to
> handle this?
>
> Cheers,
> - Ali

Without much confidence on my side, first, I think you need to make the 
constructor parameter inout(T) as well. Otherwise, you may be making a 
const(W!T) initialized with a non-const T.


After that, I like the "type constructor" syntax in main_alt() below 
(which works) but a better approach is to use a convenience function 
like wrap() below:


struct W(T) {
T val;
this(inout(T) val) inout {
this.val = val;
}
}

class C {}

void main_alt() {
auto a = W!C(new C);
auto b = immutable W!(immutable C)(new C);
}

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

void main() {
auto a = wrap(new C);
auto b = wrap(new immutable(C));
}

Ali
"taklitlerinden sakınınız" :o)



How to get an inout constructor working with a template wrapper

2018-07-22 Thread aliak via Digitalmars-d-learn

Hi,

In the code below:

struct W(T) {
T val;
this(T val) inout {
this.val = val;
}
}

class C {}

void main() {
   W!C a = new C;
   immutable W!C b = new C;
}

W!C a = new C results in: "Error: cannot implicitly convert 
expression val of type C to inout(C)."


If I remove the inout on the constructor then the error is on the 
other line and is: "Error: mutable method W!(C).W.this is not 
callable using a immutable object"


If the class is changed to a struct through,  then the 
constructor with inout works on both lines in main above.


So I guess this has something to do with reference types (As the 
same behaviour is exhibited if T == int*) What's the recommended 
way to handle this?


Cheers,
- Ali