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