www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - calling function templates

reply Jos van Uden <jvu nospam.nl> writes:
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.

module test;

import std.range;

void putNumbers(Range, T)(Range r, T start, T incr) {
     T i = start;
     while (!r.empty) {
         r.put(i);  // line 8
         i += incr;
     }
}

void main() {

     int[] arr = new int[20];
     putNumbers!(int[])(arr, 0, 3); // dyn array, bang notation

     int[] arr2 = new int[20];
     putNumbers(arr2, 0, 3); // dyn array, regular notation

     int[20] arr3;
     putNumbers!(int[])(arr3, 0, 3); // stat array, bang notation

     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
Aug 09 2009
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jos van Uden:

 I noticed that I don't always have to use the bang notation for
 function templates.
Generally function templates in D are able to infer their types by themselves, so generally you don't add the types with the !().
I played around with that a little, but got an error when I used a static
array.<
It may be a problems of ranges. D fixed-size arrays have some limitations/bugs, like you can't return them (but you can return one of them if you wrap it into a struct, weird). Bye, bearophile
Aug 09 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
And a more general note Jos van Uden: don't use D2, it's unfinished, things
don't work yet. Use a stable version of D1, like 1.042.

Bye,
bearophile
Aug 09 2009
parent reply Jos van Uden <jvu nospam.nl> writes:
bearophile wrote:
 And a more general note Jos van Uden: don't use D2, it's unfinished, things
don't work yet. Use a stable version of D1, like 1.042.
 
 Bye,
 bearophile
I'm not using the language. Just trying to learn it. Most code examples I see, require D2. Jos
Aug 09 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Jos van Uden:
 I'm not using the language. Just trying to learn it.<
To learn a programming language you have to use it some.
Most code examples I see, require D2.<
Then don't look at them, and do your own experiments, etc. Bye, bearophile
Aug 09 2009
parent Bill Baxter <wbaxter gmail.com> writes:
On Sun, Aug 9, 2009 at 9:30 AM, bearophile<bearophileHUGS lycos.com> wrote:
 Jos van Uden:
 I'm not using the language. Just trying to learn it.<
To learn a programming language you have to use it some.
Most code examples I see, require D2.<
Then don't look at them, and do your own experiments, etc.
Aw come on. I'd learn D2 if I were just getting into D now. It's where all the action is heading these days. If you don't like dealing with the bleeding edge, then yeh, D1 is better for now. But there are reasons why a person might prefer to learn either. --bb
Aug 09 2009
prev sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
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);
Aug 09 2009