digitalmars.D - opAssign and template class
- dbjdbj (3/3) Feb 05 2014 Please consider this: http://dpaste.dzfl.pl/dc4a3c29e57f
- Stanislav Blinov (6/9) Feb 05 2014 You cannot overload identity assignment for classes. It's a
- dbjdbj (4/9) Feb 05 2014 I need to be able to implement "=" operator so that this works:
- Stanislav Blinov (3/7) Feb 05 2014 You can't. Classes are reference types. This just doesn't make
- dbjdbj (7/9) Feb 05 2014 *object_alive* is what I mentioned, not object_create
- Stanislav Blinov (57/67) Feb 05 2014 Yes, but in your implementation you intend to increment both
- dbjdbj (5/5) Feb 05 2014 Impressive but please next time please use:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/16) Feb 05 2014 I disagree. dpaste has no association with this newsgroup and can
Please consider this: http://dpaste.dzfl.pl/dc4a3c29e57f What is my mistake ? Thanks ...
Feb 05 2014
On Wednesday, 5 February 2014 at 10:33:08 UTC, dbjdbj wrote:Please consider this: http://dpaste.dzfl.pl/dc4a3c29e57f What is my mistake ? Thanks ...You cannot overload identity assignment for classes. It's a language construct that rebinds a reference and cannot be overridden. Such opAssign overloading is only possible for structs. See http://dlang.org/operatoroverloading.html#Assignment.
Feb 05 2014
You cannot overload identity assignment for classes. It's a language construct that rebinds a reference and cannot be overridden. Such opAssign overloading is only possible for structs. See http://dlang.org/operatoroverloading.html#Assignment.I need to be able to implement "=" operator so that this works: auto x_ = new X(), x2 = x_ ; objects)alive needs to be 2 after. Thanks ...
Feb 05 2014
On Wednesday, 5 February 2014 at 12:29:11 UTC, dbjdbj wrote:I need to be able to implement "=" operator so that this works: auto x_ = new X(), x2 = x_ ; objects)alive needs to be 2 after. Thanks ...You can't. Classes are reference types. This just doesn't make sense: x2 = x_; does not create any new objects.
Feb 05 2014
You can't. Classes are reference types. This just doesn't make sense: x2 = x_; does not create any new objects.*object_alive* is what I mentioned, not object_create therefore it does "make sense" ... so here it is again: auto x_ = new X() , // created:1 , alive: 1 x2 = x_ ; // created:1 , alive: 2 I tried (in all of my D innocence) to implement simple but effective counter from C++ side of the "wall" ... using the CRTP idiom ...
Feb 05 2014
On Wednesday, 5 February 2014 at 13:38:08 UTC, dbjdbj wrote:Yes, but in your implementation you intend to increment both counters in opAssign.You can't. Classes are reference types. This just doesn't make sense: x2 = x_; does not create any new objects.*object_alive* is what I mentioned, not object_createtherefore it does "make sense" ... so here it is again: auto x_ = new X() , // created:1 , alive: 1 x2 = x_ ; // created:1 , alive: 2 I tried (in all of my D innocence) to implement simple but effective counter from C++ side of the "wall" ... using the CRTP idiom ...You just cannot reliably count references to class objects in D (at least, yet, see the ongoing discussions: http://forum.dlang.org/thread/lcrue7$1ho3$1 digitalmars.com, http://forum.dlang.org/thread/grngmshdtwqfaftefhky forum.dlang.org). For non-class objects, there is a library implementation, std.typecons.RefCounted. With it, you can roll something similar: import std.stdio; import std.typecons; struct Counter(T) if (!is(T == class)) { disable this(this); disable void opAssign(ref Counter); private static int objectsCreated_ = 0; private T x_; this(T x) { x_ = x; ++objectsCreated_; } static int getObjectsCreated() { return objectsCreated_; } property ref auto get() inout { return x_; } alias get this; } auto counter(T,Args...)(ref auto Args args) if (!is(T == class)) { return RefCounted!(Counter!T)(T(args)); } property auto objectsCreated(O)(ref O o) if (is(O == RefCounted!(Counter!T), T)) { return o.getObjectsCreated(); } property auto numReferences(O)(ref O o) if (is(O == RefCounted!(Counter!T), T)) { return o.refCountedStore.refCount; } struct X { int v; } struct Y { string s; } void foo(ref const X x) { writefln("%s", x.v); } void bar(ref const Y y) { writefln("%s", y.s); } void main() { auto x_ = counter!X, x2 = x_; writefln("objects created: %s, num references: %s", x_.objectsCreated, x_.numReferences); foo(x_); auto y_ = counter!Y("hello"), y2 = y_; y2.s = "world"; // Modifies y_.s too writefln("objects created: %s, num references: %s", y_.objectsCreated, y_.numReferences); bar(y_); } --- Note that e.g. typeof(x_) is actually RefCounted!(Counter!X). But you cannot do similar for classes, because you cannot guard against escaping references.
Feb 05 2014
Impressive but please next time please use: http://dpaste.dzfl.pl/ ... Depressive is this issue (and some more) since I was sincerely hoping I could live C++ "behind" ... Eh ...
Feb 05 2014
On 02/05/2014 09:37 AM, dbjdbj wrote:>Impressive but please next time please use: http://dpaste.dzfl.pl/ ...I disagree. dpaste has no association with this newsgroup and can disappear at any time in the future.Depressive is this issue (and some more) since I was sincerely hoping I could live C++ "behind" ... Eh ...There is a significant difference between D and C++. In D, classes are reference types (not value types). The equivalent in C++ of what you are trying to do would be overriding the assignment operator for class pointers, which is not possible in C++: // C++ code: X * x_ = new X() , // created:1 , alive: 1 * x2 = x_ ; // created:1 , alive: 2 (not possible!) Same limitation in D... Ali
Feb 05 2014