Any way to move in @disabled this(this) type in to a wrapping template?
Paul Backus
snarwin at gmail.com
Thu Jul 25 21:23:33 UTC 2019
On Thursday, 25 July 2019 at 20:38:59 UTC, aliak wrote:
> On Thursday, 25 July 2019 at 19:35:36 UTC, aliak wrote:
>> Basically, can template W be made to handle an S that can't be
>> copied?
>>
>> import std;
>>
>> static struct S {
>> int i;
>> @disable this(this);
>> this(int i) { this.i = i; }
>> }
>>
>> [...]
>
> So this works - are there any problems with it?
>
> struct W(T) {
> T value;
> this(T value) {
> static if (isMutable!T)
> this.value = value.move;
> else
> this.value = value;
> }
> }
>
> auto wrap(T)(T value) {
> static if (isMutable!T)
> return W!T(value.move);
> else
> return W!T(value);
> }
>
> Shouldn't this be happening by default? When would you not want
> that to happen?
The way I handle this is with `auto ref` and
`core.lifetime.forward`:
import core.lifetime: forward;
struct W(T)
{
T value;
this()(auto ref T value)
{
this.value = forward!value;
}
}
auto wrap(T)(auto ref T value)
{
return W!T(forward!value);
}
@safe unittest
{
static struct NoCopy { @disable this(this); }
assert(__traits(compiles, {
auto test = wrap(NoCopy());
}));
assert(!__traits(compiles, {
auto lval = NoCopy(); auto test = lval;
}));
}
Interactive: https://run.dlang.io/is/kDJyYC
It's not very well documented, but `forward` does essentially the
same thing as your `static if` + `move` combination.
Note that with both your version and mine, you will run into the
same problem I did of `move` making it impossible to use
instances of `W` in static initializers and CTFE. [1] The best
compromise I was able to come up with was to only call move if
`isCopyable!T == false`, which doesn't really solve the problem,
but at least contains it.
[1] https://github.com/pbackus/sumtype/issues/22
More information about the Digitalmars-d-learn
mailing list