Cannot always deduce template arguments when using implicitly cast array literals

Paul Backus snarwin at gmail.com
Fri Jul 23 14:41:41 UTC 2021


On Friday, 23 July 2021 at 13:53:27 UTC, Rekel wrote:
> After simplifying a part of my code I found the following code 
> cannot deduce the template arguments, but I have no clue why.
>
> ```d
> void foo(L : T[L1][L2], uint L1, uint L2, T, R:
> 		T[L1])(const L left, const R right) {
> 	// Function
> }
>
> void bar(uint L)(float[L] l) {
> 	// Function
> }
>
> void main(string[] args) {
> 	bar([1.0f, 2, 3, 4, 5, 6, 7, 8]); // implicitly cast to 
> float[8], works
> 	float[4][1] l = [[1, 2, 3, 4]];
> 	foo!(typeof(l), 4, 1, float, float[4])(l, [1.0f, 2, 3, 4]); // 
> also works
> 	foo(l, [1.0f, 2, 3, 4]); // cannot deduce function from 
> argument types (?)
> }
> ```
>
> As one can see, implicitly casting array literals in templates 
> works fine in the case of bar, as does explicit use of 
> templates in the case of foo, but for some reason foo does not 
> manage to deduce its arguments like bar does.

Looks like the problem is that the compiler is interpreting 
`[1.0f, 2, 3, 4]` as a dynamic array (`float[]`) instead of a 
static array (`float[4]`).

Array literals are treated as dynamic arrays by default, and as 
static arrays only in specific contexts where the compiler is 
able to determine that a static array is required. Unfortunately, 
the algorithm it uses for this is not very sophisticated, and 
does not take type specializations (like `R : T[L1]`) into 
account.

There are two ways you can solve this. The first is to change the 
type of `right` from `const R` to `const T[L1]`, which removes 
the type specialization:

```d
void foo(L : T[L1][L2], uint L1, uint L2, T)
         (const L left, const T[L1] right)
{
	// Function
}
```

The second is to use `std.array.staticArray` to manually cast the 
array literal to a static array:

```d
     import std.array: staticArray;
     foo(l, staticArray!([1.0f, 2, 3, 4]));
```


More information about the Digitalmars-d-learn mailing list