calling function templates

Daniel Keep daniel.keep.lists at gmail.com
Sun Aug 9 10:44:20 PDT 2009



Jos van Uden wrote:
> I noticed that I don't always have to use the bang notation for
> function templates. I played around with that a little, but got
> an error when I used a static array. I think it's because of a
> casting problem or wrong type inference... I don't imagine it's
> a bug. Just not possible.
> 
> ...
> 
>     int[20] arr4;
>     putNumbers(arr4, 0, 3); // ERROR, stat array, regular notation
> 
> }
> 
> test.d(8): Error: cast(int[])r is not an lvalue
> test.d(25): Error: template instance test.putNumbers!(int[20u],int)
> error instantiating

You're instantiating the template as putNumbers!(int[20u],int) because
arr4 is of type int[20u].

This means Range is int[20u].  Here's the code for put:

> void put(T, E)(ref T[] a, E e) {
>     assert(a.length);
>     a[0] = e; a = a[1 .. $];
> }

r.put(i) is rewritten by the compiler as put(r, i)... except that put
wants an int[], not an int[20u].  So it implicitly casts it to the
correct type, giving put(cast(int[])r, i).

But put ALSO expects its first argument to be passed by reference, and
you cannot pass the result of a cast by-reference.

(There are a LOT of things you can't pass by reference; it's a constant
thorn in my side, and many others' sides.)

The problem here is that put is fundamentally incompatible with
fixed-size arrays.  The solution is to change line 25 to read:

auto arr4_temp = arr4[]; putNumbers(arr4_temp, 0, 3);


More information about the Digitalmars-d-learn mailing list