Last night I encountered some strange behavior of the dup function.
import std.stdio;
struct S {
int x;
int y;
int[] arr;
this(ref return scope const S rhs) {
writeln("copy ctor");
this.x = rhs.x;
this.y = rhs.y;
this.arr = rhs.arr.dup;
}
}
void main() {
const S[] array = [S(0, 0), S(1, 2)];
S[] copy = array.dup; // error
}
We have an issue:
Error: none of the overloads of template `object.dup` are callable using argument types `!()(const(S[]))`
But(!) if we remove the dynamic array field from the structure, everything works.
I decided to get around the problem by writing my own function to copy arrays:
T[] copyArray(T)(const T[] arr) {
T[] copy = new T[arr.length];
for (size_t i = 0; i < arr.length; i++) {
copy[i] = arr[i]; // error
}
return copy;
}
void main() {
const S[] array = [S(0, 0), S(1, 2)];
S[] copy = copyArray(array);
}
Nice, simple function, but it doesn't compile on the assignment line:
Error: cannot implicitly convert expression `arr[i]` of type `const(S)` to `S`
(The feature is the same: if we remove the dynamic array field from the structure, everything works.)
An additional variable solution worked:
T[] copyArray(T)(const T[] arr) {
T[] copy = new T[arr.length];
for (size_t i = 0; i < arr.length; i++) {
T elem = arr[i]; // copy ctor is called
copy[i] = elem; // copy ctor isn't called!
}
return copy;
}
I feel that I do not understand something, please explain what is the problem of constant structures with reference fields?
And why is the copy constructor only called once in the last example? Optimization?
Permalink
Reply