Assigning a static array
Steven Schveighoffer
schveiguy at yahoo.com
Thu Apr 18 14:54:06 PDT 2013
> There is a similar problem with the automatically generated array
> arguments.
>
> The following constructor takes any number of ints that come in array
> form:
>
> import std.stdio;
>
> struct S
> {
> int[] a;
>
> this(int[] args...)
> {
> a = args;
> }
>
> void foo()
> {
> writeln(a);
> }
> }
>
> void main()
> {
> S[] a;
>
> foreach (i; 0 .. 2) {
> a ~= S(i, i, i); // <-- WARNING temporary array
> }
>
> foreach (e; a) {
> e.foo();
> }
> }
>
> The program prints the following because the temporary arrays that are
> generated when calling the constructors are long gone:
>
> [1, 1, 1]
> [1, 1, 1]
>
> The programmer *may have* ;) expected the following output:
>
> [1, 1, 1]
> [2, 2, 2]
There is no guarantee that the incoming array from a variadic function is
heap-based.
But an interesting way to deal with it is that you can overload with an
explicit slice parameter, and the variadic version will ONLY bind to a
variadic call.
For example, in dcollections' ArrayList I have two constructors:
/**
* Create an array list based on a number of elements.
*/
this(V[] elems...)
{
_array = elems.dup;
}
/**
* Use an array as the backing storage. This does not duplicate the
* array. Use new ArrayList(storage.dup) to make a distinct copy.
Beware
* of using a stack-based array when using this constructor!
*/
this(V[] storage)
{
_array = storage;
}
The first version binds only to cases where the parameter is not
*explicitly* a slice, so I am guaranteed that the array is allocated on
the stack! The second binds to slices, and I assume from my comment,
fixed-sized arrays (been a while since I looked at that code).
And the correct expectation for your code should be:
[0, 0, 0]
[1, 1, 1]
:)
-Steve
More information about the Digitalmars-d-learn
mailing list