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