www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - templated static array

reply "Namespace" <rswhite4 googlemail.com> writes:
How can I do this?

I have this code: http://dpaste.dzfl.pl/d9165502

And as you can see, the templated function 'receive2' take 
automatically dynamic arrays. But how can I tell the compiler, 
that this function takes (preferably) static arrays?
My little "hack" function 'receive' take the type and the number 
of elements. So the compiler know: it's a static array. But is 
there no simpler trick to do this?
Maybe something like 'void receive(T)(static T vals) {'.
Oct 15 2012
next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2012-05-15 16:10, Namespace <rswhite4 googlemail.com> wrote:

 How can I do this?

 I have this code: http://dpaste.dzfl.pl/d9165502

 And as you can see, the templated function 'receive2' take automatically  
 dynamic arrays. But how can I tell the compiler, that this function  
 takes (preferably) static arrays?
 My little "hack" function 'receive' take the type and the number of  
 elements. So the compiler know: it's a static array. But is there no  
 simpler trick to do this?
 Maybe something like 'void receive(T)(static T vals) {'.

Nope. That's the way to do it. -- Simen
Oct 15 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Namespace:

 I have this code: http://dpaste.dzfl.pl/d9165502

void receive(alias n, T)(T[n] vals) { No need to use alias there, this is better: void receive(size_t n, T)(T[n] vals) {
 But how can I tell the compiler, that this function takes 
 (preferably) static arrays?

Define "preferably" please. Often template constraints are able to do many things (and there is a isStaticArray trait). Bye, bearophile
Oct 15 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
So there is no way that the compiler knows by himself how many 
elements are in the array? something like this:

void receive(T, size_t n = vals.length)(T[n] vals) {
	writeln(typeof(vals).stringof);
}

or:

void receive(T)(T[vals.length] vals) {
	writeln(typeof(vals).stringof);
}
Oct 15 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Namespace:

 So there is no way that the compiler knows by himself how many 
 elements are in the array?

The syntax I have suggested doesn't have the problem you fear. Why don't you compile and run a little test program? Bye, bearophile
Oct 15 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
On Monday, 15 October 2012 at 15:10:43 UTC, bearophile wrote:
 Namespace:

 So there is no way that the compiler knows by himself how many 
 elements are in the array?

The syntax I have suggested doesn't have the problem you fear. Why don't you compile and run a little test program? Bye, bearophile

I have: http://dpaste.dzfl.pl/661e4fb3 But I still have to specify the number of elements and the type. That is what I try to avoid.
Oct 15 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2012-23-15 16:10, Simen Kjaeraas <simen.kjaras gmail.com> wrote:

 On 2012-05-15 16:10, Namespace <rswhite4 googlemail.com> wrote:

 How can I do this?

 I have this code: http://dpaste.dzfl.pl/d9165502

 And as you can see, the templated function 'receive2' take  
 automatically dynamic arrays. But how can I tell the compiler, that  
 this function takes (preferably) static arrays?
 My little "hack" function 'receive' take the type and the number of  
 elements. So the compiler know: it's a static array. But is there no  
 simpler trick to do this?
 Maybe something like 'void receive(T)(static T vals) {'.

Nope. That's the way to do it.

No, wait, sorry. You don't need to specify those things when calling the function. This works: void bar(T, size_t n)(T[n] a) {} void main(){ int[3] a; bar(a); } -- Simen
Oct 15 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
But bar([1, 2, 3]); not. The compiler does not realize that [1, 
2, 3] means a static array in this context.
You have to write bar(cast(int[3]) [1, 2, 3]); but I think the 
compiler have to recognize this on it's own.
Oct 15 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2012-35-15 17:10, Namespace <rswhite4 googlemail.com> wrote:

 But bar([1, 2, 3]); not. The compiler does not realize that [1, 2, 3]  
 means a static array in this context.
 You have to write bar(cast(int[3]) [1, 2, 3]); but I think the compiler  
 have to recognize this on it's own.

This is true. The problem is, as you say, that the compiler treats array literals as dynamic rather than static arrays. I would argue this is the correct default, but it's obviously not the default you want here. bearophile has posted about this on numerous occasions, and it's among his top thousand wanted features. :p -- Simen
Oct 15 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Oct 15, 2012 at 07:05:13PM +0200, Simen Kjaeraas wrote:
 On 2012-35-15 17:10, Namespace <rswhite4 googlemail.com> wrote:
 
But bar([1, 2, 3]); not. The compiler does not realize that [1, 2, 3]
means a static array in this context.  You have to write
bar(cast(int[3]) [1, 2, 3]); but I think the compiler have to
recognize this on it's own.

This is true. The problem is, as you say, that the compiler treats array literals as dynamic rather than static arrays. I would argue this is the correct default, but it's obviously not the default you want here. bearophile has posted about this on numerous occasions, and it's among his top thousand wanted features. :p

I have to chime in here and say that I'm not particularly happy with the way dmd currently processes array literals. I think dmd currently doesn't take type inference far enough. If a particular array literal is being passed to a function that expects a static array, say, then it should be able to interpret the literal as a static array of the matching type. Similarly, when you have, say, a template function: func(T)(T[] args) if (is(T==short)) { ... } Supposing there is no other overload that accepts an integral array, the compiler should know that when you write func([1,2,3]) the array literal should be a short[]. Currently, it treats [1,2,3] as int[], and so fails to match the template. Lots of ugly hacks and workarounds are necessary to make things work correctly. I say this is one area where things need improvement. Especially since type inference is one of D's major selling points (what with voldemort types, etc., that doesn't require the user to spell out a long complicated name just to use a range function in std.range, among many other nice perks). T -- Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon Bonaparte
Oct 15 2012
prev sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
On Monday, 15 October 2012 at 17:05:30 UTC, Simen Kjaeraas wrote:
 On 2012-35-15 17:10, Namespace <rswhite4 googlemail.com> wrote:

 But bar([1, 2, 3]); not. The compiler does not realize that 
 [1, 2, 3] means a static array in this context.
 You have to write bar(cast(int[3]) [1, 2, 3]); but I think the 
 compiler have to recognize this on it's own.

This is true. The problem is, as you say, that the compiler treats array literals as dynamic rather than static arrays. I would argue this is the correct default, but it's obviously not the default you want here. bearophile has posted about this on numerous occasions, and it's among his top thousand wanted features. :p

I think this is a bug in IFTE. Please file it into bugzilla. Kenji Hara
Oct 15 2012