opAssign and template class
Stanislav Blinov
stanislav.blinov at gmail.com
Wed Feb 5 05:46:14 PST 2014
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.
More information about the Digitalmars-d
mailing list