opAssign and const?
Era Scarecrow
rtcvb32 at yahoo.com
Fri May 4 20:15:00 PDT 2012
On Saturday, 5 May 2012 at 02:21:06 UTC, Jonathan M Davis wrote:
> As I understand it, you don't need to do _anything_ special to
> avoid having a temporary copied when passed to your function.
> Because it's a temporary, it should be moved into the function
> parameter, not copied. No postblit or opAssign will be
> executed. It's only when it's _not_ a temporary that a copy
> will be made. And even in _that_ case, it should be a move if
> that function call is the last place that the variable is used.
That's what I originally thought too... But when I'm dealing
with the temporary there's something broken. So if I only have
only the ref.
Error: function X.opAssign (ref X rhs) is not callable using
argument types (X)
so;
struct X {
ref X opAssign(ref X rhs);
}
X func();
struct Y {
X x;
this() {
x = func();
}
}
Unless there's a default it drops back to, it is only seeing the
one assign function.
> So, I believe that you're trying to avoid copies that will
> never happen anyway. They would if you were dealing with C++ -
> particularly C++98 - but not in D (C++11 fixes the problem via
> move constructors).
I'm not trying to avoid copying (Blocks are small so it's likely
a tiny cost); I'm trying to keep arrays separate. Let's add to
my example; I Hope I got it right based on the behavior I'm
seeing.
struct X {
ubyte[] buffer;
this(ubyte[] b) {
buffer = b;
}
ref X opAssign(ref X rhs);
}
X func() {
return X(new ubyte[5]);
}
void func2(){
ubyte[15] buff;
X x1 = X(buff[0 .. 5]);
X x2 = X(buff[5 .. 10]);
const X x3 = X(buff[10 .. $]);
x1 = x2; //should use ref, opAssign required to keep addresses
separate
assert(x1.buff !is x2.buff); //must pass, else value semantics
I'm using breaks
x1 = func(); //default copy can work, but fails due to
opAssign(ref X) existing. Works with opAssign(X)
x1 = x3; //should fail and needs a (const X) or (ref const X).
//but if you change to (ref const X),
x1 = x2; //then opAssign(X) runs, making arrays x1 & x2 point
to the same place; not what i want.
}
In my thinking i make (ref const X) then mutable versions should
work too; but somehow it's deciding to use (X) instead of (ref
const X). I'm promising I won't change the data, not requiring
the data can't be changed.
More information about the Digitalmars-d-learn
mailing list