www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opAssign and template class

reply "dbjdbj" <dbj dbj.org> writes:
Please consider this: http://dpaste.dzfl.pl/dc4a3c29e57f

What is my mistake ?

Thanks ...
Feb 05 2014
parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
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
parent reply "dbjdbj" <dbj dbj.org> writes:
 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
parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
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
parent reply "dbjdbj" <dbj dbj.org> writes:
 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
parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Wednesday, 5 February 2014 at 13:38:08 UTC, dbjdbj wrote:
 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
Yes, but in your implementation you intend to increment both counters in opAssign.
 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 ...
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
parent reply "dbjdbj" <dbj dbj.org> writes:
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
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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