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