On Mon, 14 Feb 2011 21:18:39 -0500, jam <[email protected]> wrote:
Hi all,
Just curious as to the difference in the built-in variable length
array vs. the std.container.Array and fixed length arrays when it
comes to using them in functions that take Ranges.
For instance the following does not compile:
import std.algorithm;
import std.stdio;
import std.range;
import std.conv;
import std.container;
import std.array;
void main() {
int[5] builtin_fixed;
int[] builtin_variable;
Array!(int) con_array;
con_array.length(5);
builtin_variable.length = 5;
fill(builtin_variable, 9); //ok, no error
isSorted(builtin_variable); //ditto
//The following 4 statements produce errors
fill(builtin_fixed, 9);
fill(con_array, 9);
isSorted(con_array);
isSorted(builtin_fixed);
}
The errors are variations on:
Error: template std.algorithm.fill(Range,Value) if
(isForwardRange!(Range) && is(typeof(range.front = filler))) does not
match any function template declaration
Error: template std.algorithm.fill(Range,Value) if
(isForwardRange!(Range) && is(typeof(range.front = filler))) cannot
deduce template function from argument types !()(int[5LU],int)
If I change those 4 statements to:
fill(builtin_fixed[], 9);
fill(con_array[], 9);
isSorted(con_array[]);
isSorted(builtin_fixed[]);
effectively passing ranges (std.container.Array!(int).Array.Range in
the case of con_array, and int[] for builtin_fixed) which then works
as expected. This all makes sense, and it's easy enough to write
wrappers, but I would (well and I did) expect the first way to just
work. This may just be a nitpick I guess, but being new to the
language this little detour involved quite a bit of time research (not
a bad thing, I did learn quite a bit in the process), but makes me
wonder if I am missing something fundamental regarding when I should
be using these different array types.
This is because:
1. a fixed-sized array is not a range. It is passed by value, not by
reference. The problem there is IFTI thinking you want to pass the fixed
array as a fixed array and not as a slice.
2. a container is not a range. An Array is a container, so you must
extract a range from it to use it in range-like activities.
The second point seems odd, since builtin arrays are ranges, but an Array
is different because it's a true reference type (changing the length from
one reference alters the length of another reference) and it "owns" the
memory contained within, unlike a builtin array which just references the
memory.
But it's also easy to consider other things. Consider a RedBlackTree
container, should that be a range? What happens when you popFront?
-Steve