Copying structs with pointers

Peter Alexander peter.alexander.au at gmail.com
Wed Jul 20 14:49:50 PDT 2011


Just came across this issue today. I wanted to create a typical value 
type wrapper around a heap allocated object. I even created a nice 
postblit constructor like a good D programmer.


struct Ptr
{
   private int* p;
   this(int x) { p = new int; *p = x; }
   this(this) { int x = *p; p = new int; *p = x; }
   ...
}

void main()
{
   const Ptr a = Ptr(1);
   Ptr b = a; // error
}


Problem is, this code is illegal because you can't create a non-const 
copy of a const value type that contains pointers or references (due to 
transitive const).

I can get around it in this particular instance by creating a dup 
property (like a C++ copy constructor):

struct Ptr
{
   @property const Ptr dup()
   {
     return Ptr(*p);
   }
}

But it still means that my struct is non-copyable in general. For 
example, I can't fill a range with a const Ptr.

const Ptr a = Ptr(1);
Ptr[10] arr;
std.algorithm.fill(arr[], a); // error


I understand why the shallow copy isn't allowed in general (it would 
break transitive const), but as the dup property demonstrates, I am able 
to create a deep copy of Ptr without violating const-correctness -- the 
problem is that I am not able to express this using a postblit constructor.

Am I missing something? How are you supposed to define value semantics 
on structs containing pointers?


More information about the Digitalmars-d mailing list