digitalmars.D.learn - why property cannot be pass as ref ?
- ChangLong (22/22) Dec 20 2017 =======
- =?UTF-8?Q?Ali_=c3=87ehreli?= (18/38) Dec 20 2017 The problem is not with opAssign but with left(), which returns an
- Mengu (3/11) Dec 20 2017 was just reading this:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (33/37) Dec 20 2017 Thanks to Mengü for linking to that section. I have to make corrections...
- ChangLong (33/36) Dec 29 2017 Thanks for explain, Ali And Mengu.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (46/95) Jan 02 2018 I hope others can answer that. For what it's worth, here is an earlier
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (46/48) Jan 03 2018 Have you considered std.typecons.Unique[0]? If yes, in what ways
- ChangLong (10/60) Jan 03 2018 Thanks for explain. I need add version number and other check
======= struct A { alias This = typeof(this) ; void opAssign(ref This ){ } ref auto left(){ return This() ; } } void main(){ A root ; ref find() { auto p = root ; p = p.left; } } =========== test.d(16): Error: function tree.A.opAssign (ref A _param_0) is not callable using argument types (A) Is this by design ?
Dec 20 2017
On 12/20/2017 07:02 AM, ChangLong wrote:======= struct A { alias This = typeof(this) ; void opAssign(ref This ){ } ref auto left(){ return This() ; } } void main(){ A root ; ref find() { auto p = root ; p = p.left; } } =========== test.d(16): Error: function tree.A.opAssign (ref A _param_0) is not callable using argument types (A) Is this by design ?The problem is not with opAssign but with left(), which returns an rvalue. It's by design that rvalues cannot be bound to references in D. The code compiles if left() returns an lvalue: ref auto left(){ // return This() ; return *l; } This *l; What you can do is to convert opAssign to a template with an additional set of parameters and change its parameter to 'auto ref': void opAssign()(auto ref This ){ } 'auto ref' essentially generates two copies of the function: one taking by-value for rvalues and one taking by-ref for lvalues. So, be aware that you cannot use the address of the argument because in the case of rvalues its a local variable (copy of the actual argument). Ali
Dec 20 2017
On Wednesday, 20 December 2017 at 18:04:57 UTC, Ali Çehreli wrote:On 12/20/2017 07:02 AM, ChangLong wrote:was just reading this: https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-ref-and-then-not-using-it[...]is not[...]The problem is not with opAssign but with left(), which returns an rvalue. It's by design that rvalues cannot be bound to references in D. [...]
Dec 20 2017
Thanks to Mengü for linking to that section. I have to make corrections below. On 12/20/2017 10:04 AM, Ali Çehreli wrote:'auto ref' essentially generates two copies of the function: one taking by-value for rvaluesNote that by-value for rvalues means "blitting" in D (blit: bit-level transfer).in the case of rvalues its a local variable (copy of the actual argument).I was wrong there: The local variable is the actual argument blitted in to the function. The post-blit is never executed for rvalues. The following program does *not* print "post-blit": import std.stdio; struct S { int i; this (int i) { this.i = i; writeln("&this : ", &this); } this(this) { writeln("post-blit"); } } void foo()(auto ref S s) { writeln("&s : ", &s); } void main() { auto lvalue = S(1); foo(lvalue); foo(S(2)); // rvalue } &this : 7FFF23ED08A8 <-- lvalue &s : 7FFF23ED08A8 <-- by-ref lvalue &this : 7FFF23ED08AC <-- rvalue &s : 7FFF23ED0890 <-- blitted rvalue Ali
Dec 20 2017
On Wednesday, 20 December 2017 at 18:43:21 UTC, Ali Çehreli wrote:Thanks to Mengü for linking to that section. I have to make corrections below. AliThanks for explain, Ali And Mengu. What I am try to do is implement a unique data type. (the ownership auto moved into new handle) consider this code: import std.stdio; struct S { disable this(this); void* socket; this (void* i) { socket = i; } void opAssign()(auto ref S s ){ socket = s.socket ; s.socket = null ; } nogc safe ref auto byRef() const pure nothrow return { return this; } } void main() { static __gshared size_t socket; auto lvalue = S(&socket); // pass rvalue into lvalue, working S l2 = void; l2 = lvalue; // pass lvalue into lvalue, working auto l3 = l2.byRef; // pass lvalue into lvalue, not working } I can not assign l2 to l3 because "Error: struct app.S is not copyable because it is annotated with disable", but it working if I init l3 with void.
Dec 29 2017
On 12/29/2017 07:49 PM, ChangLong wrote:On Wednesday, 20 December 2017 at 18:43:21 UTC, Ali Çehreli wrote:I hope others can answer that. For what it's worth, here is an earlier experiment that Vittorio Romeo and I had played with at C++Now 2017. It uses std.algorithm.move: import std.stdio; import std.algorithm; int allocate() { static int i = 42; writeln("allocating ", i); return i++; } void deallocate(int i) { writeln("deallocating ", i); } struct UniquePtr { int i = 666; // To easily differentiate UniquePtr.init from 0 this(int i) { this.i = i; } ~this() { deallocate(i); } disable this(this); } void use(UniquePtr p) { writeln("using ", p.i); } UniquePtr producer_rvalue(int i) { return i % 2 ? UniquePtr(allocate()) : UniquePtr(allocate()); } UniquePtr producer_lvalue() { writeln("producer_lvalue"); auto u = UniquePtr(allocate()); writeln("allocated lvalue ", u.i); return u; } void main() { use(UniquePtr(allocate())); auto u = UniquePtr(allocate()); use(move(u)); auto p = producer_rvalue(0); use(move(p)); auto p2 = producer_lvalue(); use(move(p2)); } AliThanks to Mengü for linking to that section. I have to make corrections below. AliThanks for explain, Ali And Mengu. What I am try to do is implement a unique data type. (the ownership auto moved into new handle) consider this code: import std.stdio; struct S { disable this(this); void* socket; this (void* i) { socket = i; } void opAssign()(auto ref S s ){ socket = s.socket ; s.socket = null ; } nogc safe ref auto byRef() const pure nothrow return { return this; } } void main() { static __gshared size_t socket; auto lvalue = S(&socket); // pass rvalue into lvalue, working S l2 = void; l2 = lvalue; // pass lvalue into lvalue, working auto l3 = l2.byRef; // pass lvalue into lvalue, not working } I can not assign l2 to l3 because "Error: struct app.S is not copyable because it is annotated with disable", but it working if I init l3 with void.
Jan 02 2018
On Saturday, 30 December 2017 at 03:49:37 UTC, ChangLong wrote:What I am try to do is implement a unique data type. (the ownership auto moved into new handle)Have you considered std.typecons.Unique[0]? If yes, in what ways does it not cover your needs? Your example code written with Unique would be something like the below, with some additions to show off more of what it can do: import std.typecons : Unique; import std.algorithm.mutation : move; void test1(size_t i) {} void test2(ref size_t i) {} void test3(ref Unique!size_t i) {} void test4(Unique!size_t i) {} unittest { static __gshared size_t socket; auto l1 = Unique!(size_t)(&socket); assert(l1 == &socket); Unique!(size_t) l2 = void; assert(!is(typeof({ l2 = l1; // Fails to compile - cannot copy Unique. }))); move(l1, l2); // Explicit move using std.algorithm.mutation.move. assert(l1 == null); // l1 has been cleared - only one reference to the data exists. assert(l2 == &socket); // l2 has the only reference. auto l3 = l2.release; // Implicit move, not unlike your byRef call. assert(l2 == null); // l2 has been cleared - only one reference to the data exists. assert(l3 == &socket); // l3 has the only reference. assert(!is(typeof({ auto l4 = l3; // Fails to compile - cannot copy Unique. }))); test1(*l3); // Can dereference and pass the pointed-to value. test2(*l3); // Can pass reference to pointed-to value[1]. test3(l3); // Lets you pass references to Unique. assert(!is(typeof({ test4(l3); // Fails to compile - cannot copy Unique. }))); } [0]: https://dlang.org/library/std/typecons/unique.html [1]: This surprised me a little - that's a new reference to the pointed-to value, which the callee could squirrel away somewhere it shouldn't. I guess it's there for ease of use. -- Simen
Jan 03 2018
On Wednesday, 3 January 2018 at 08:51:55 UTC, Simen Kjærås wrote:On Saturday, 30 December 2017 at 03:49:37 UTC, ChangLong wrote:Thanks for explain. I need add version number and other check into the UniqueType, std.typecons : Unique is is not suit. std.algorithm.mutation : move is what I am look for. but I don't understand why this code not working since I already add void opAssign(ref This ) to UniqueType. Unique!(size_t) l1 = Unique!(size_t)(&socket); Unique!(size_t) l2 = void; l2 = l1; // assign left value into left value, Unique is not copyable because it is annotated with disableWhat I am try to do is implement a unique data type. (the ownership auto moved into new handle)Have you considered std.typecons.Unique[0]? If yes, in what ways does it not cover your needs? Your example code written with Unique would be something like the below, with some additions to show off more of what it can do: import std.typecons : Unique; import std.algorithm.mutation : move; void test1(size_t i) {} void test2(ref size_t i) {} void test3(ref Unique!size_t i) {} void test4(Unique!size_t i) {} unittest { static __gshared size_t socket; auto l1 = Unique!(size_t)(&socket); assert(l1 == &socket); Unique!(size_t) l2 = void; assert(!is(typeof({ l2 = l1; // Fails to compile - cannot copy Unique. }))); move(l1, l2); // Explicit move using std.algorithm.mutation.move. assert(l1 == null); // l1 has been cleared - only one reference to the data exists. assert(l2 == &socket); // l2 has the only reference. auto l3 = l2.release; // Implicit move, not unlike your byRef call. assert(l2 == null); // l2 has been cleared - only one reference to the data exists. assert(l3 == &socket); // l3 has the only reference. assert(!is(typeof({ auto l4 = l3; // Fails to compile - cannot copy Unique. }))); test1(*l3); // Can dereference and pass the pointed-to value. test2(*l3); // Can pass reference to pointed-to value[1]. test3(l3); // Lets you pass references to Unique. assert(!is(typeof({ test4(l3); // Fails to compile - cannot copy Unique. }))); } [0]: https://dlang.org/library/std/typecons/unique.html [1]: This surprised me a little - that's a new reference to the pointed-to value, which the callee could squirrel away somewhere it shouldn't. I guess it's there for ease of use. -- Simen
Jan 03 2018