digitalmars.D.learn - advise about safety of using move in an opAssign with __traits(isRef
- aliak (41/41) Aug 16 2019 Hi, I'm trying to fix a use-case where you have a wrapper
- Paul Backus (6/26) Aug 16 2019 Even simpler:
- aliak (5/12) Aug 17 2019 That doesn't work with private members unfortunately :( - i.e.
- Paul Backus (16/26) Aug 17 2019 Are you sure? I tried to reproduce the error you're describing,
- aliak (16/46) Aug 18 2019 You'll get the error if you define an opAssign:
Hi, I'm trying to fix a use-case where you have a wrapper template type (it's an optional) and the wrapping type has disable this(this). And having this scenario work: struct S { disable this(this); } Optional!S fun() {...} Optional!S a; a = fun.move; Now that won't work because of the disabled copy, but you can either: 1) Add an explicit move function in the Optional type: struct Optional { auto move(ref Optional!T target) { import std.algorithm: move; return move(this, target); } } Then you could do: fun.move(field); First of all I find the readability confusing, so there's no way to know if fun is moving in to field or field is moving in to fun. But OTOH it matches the phobos move(T src, T target). So conventionally maybe ok. Also it's explicit, so it makes it clear at the call site that a move is happening. 2) use isRef inside opAssign like this: void opAssign(auto ref Optional!T lhs) { static if (__traits(isRef, lhs)) { this._value = lhs._value; } else { import std.algorithm: move; move(lhs._value, this._value); } } Then you could just do: field = fun And it'll just work since fun returns an rvalue. The second solution it seems like it'll just work correctly with the static if guard. But I'm not sure if there're any gotchas I should be aware of? Any advice?
Aug 16 2019
On Friday, 16 August 2019 at 08:07:28 UTC, aliak wrote:Hi, I'm trying to fix a use-case where you have a wrapper template type (it's an optional) and the wrapping type has disable this(this). And having this scenario work: [...] 2) use isRef inside opAssign like this: void opAssign(auto ref Optional!T lhs) { static if (__traits(isRef, lhs)) { this._value = lhs._value; } else { import std.algorithm: move; move(lhs._value, this._value); } } Then you could just do: field = fun And it'll just work since fun returns an rvalue. The second solution it seems like it'll just work correctly with the static if guard. But I'm not sure if there're any gotchas I should be aware of? Any advice?Even simpler: void opAssign(auto ref Optional!T rhs) { import core.lifetime: forward; this._value = forward!rhs; }
Aug 16 2019
On Friday, 16 August 2019 at 14:29:26 UTC, Paul Backus wrote:On Friday, 16 August 2019 at 08:07:28 UTC, aliak wrote:That doesn't work with private members unfortunately :( - i.e. this.value = forward!(rhs._value) - member inaccessible. Is there a known workaround for that? If not then should I just copy the implementation in place to be correct?[...]Even simpler: void opAssign(auto ref Optional!T rhs) { import core.lifetime: forward; this._value = forward!rhs; }
Aug 17 2019
On Friday, 16 August 2019 at 08:07:28 UTC, aliak wrote:Hi, I'm trying to fix a use-case where you have a wrapper template type (it's an optional) and the wrapping type has disable this(this). And having this scenario work: struct S { disable this(this); } Optional!S fun() {...} Optional!S a; a = fun.move; Now that won't work because of the disabled copyAre you sure? I tried to reproduce the error you're describing, and I couldn't do it. The following compiles and runs without any issues: struct Wrapper(T) { T value; } struct NoCopy { disable this(this); } Wrapper!NoCopy fun() { return Wrapper!NoCopy(); } void main() { Wrapper!NoCopy a; a = fun(); // already an rvalue, so moved implicitly } Can you give a more complete example of the problem you're having?
Aug 17 2019
On Saturday, 17 August 2019 at 16:43:51 UTC, Paul Backus wrote:On Friday, 16 August 2019 at 08:07:28 UTC, aliak wrote:You'll get the error if you define an opAssign: struct Wrapper(T) { T value; void opAssign(U : T)(Wrapper!U other) { this.value = other.value; } } struct S { disable this(this); } Wrapper!S fun() { return Wrapper!S(S()); } void main() { Wrapper!S a; a = fun; }Hi, I'm trying to fix a use-case where you have a wrapper template type (it's an optional) and the wrapping type has disable this(this). And having this scenario work: struct S { disable this(this); } Optional!S fun() {...} Optional!S a; a = fun.move; Now that won't work because of the disabled copyAre you sure? I tried to reproduce the error you're describing, and I couldn't do it. The following compiles and runs without any issues: struct Wrapper(T) { T value; } struct NoCopy { disable this(this); } Wrapper!NoCopy fun() { return Wrapper!NoCopy(); } void main() { Wrapper!NoCopy a; a = fun(); // already an rvalue, so moved implicitly } Can you give a more complete example of the problem you're having?
Aug 18 2019