Re: Cannot always deduce template arguments when using implicitly cast array literals

2022-04-21 Thread HuskyNator via Digitalmars-d-learn

On Friday, 23 July 2021 at 13:53:27 UTC, Rekel wrote:
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.


Interestingly enough, I ran into the same issue recently, but 
with a much simpler piece of code:


```d
module app;
import std.stdio;

struct One(T, uint L) {
T[L] array;

bool opEquals(T2)(const T2[L] rhs) const {
return true;
}
}

struct Two(T, uint L) {
T[L][L] array;

bool opEquals(T2)(const T2[L][L] rhs) const {
return true;
}
}

void foo() {
auto a = One!(float, 2)([1, 2]);
int[2] b = [1, 2];

writeln(a == b); // True
writeln(a.array == b); // True

writeln(a == [1, 2]); // True
writeln(a.array == [1, 2]); // True
}

void bar() {
auto a = Two!(float, 2)([[1, 2], [3, 4]]);
int[2][2] b = [[1, 2], [3, 4]];

writeln(a == b); // True
writeln(a.array == b); // True

	writeln(a == [[1, 2], [3, 4]]); // cannot deduce function from 
argument types `!()(int[][])`

writeln(a.array == [[1, 2], [3, 4]]); // True
}

void main(){
foo();
bar();
}
```

I'd love to know if there's any plans on changing/fixing this. I 
haven't been able to find any mention of it apart from in this 
thread.


Kind regards,
~ HN
(/Rekel: name change & account loss. It'd be nice if the forum 
supported editing & profiles (including posts/comments or at 
least login credential retrieval (like https://code.dlang.org/ 
does))


Re: Cannot always deduce template arguments when using implicitly cast array literals

2021-07-23 Thread Rekel via Digitalmars-d-learn

On Friday, 23 July 2021 at 14:41:41 UTC, Paul Backus wrote:
The first is to change the type of right from const R to const 
T[L1], which removes the type specialization:


Thanks for suggesting that fix, removing R altogether is a very 
simple solution I hadn't considered. :)


Unfortunately, the algorithm it uses for this is not very 
sophisticated, and does not take type specializations (like `R 
: T[L1]`) into account.


This seems like a slight oversight to me, do you know if there 
would be any chance of this changing in the future?


Re: Cannot always deduce template arguments when using implicitly cast array literals

2021-07-23 Thread Paul Backus via Digitalmars-d-learn

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]));
```


Cannot always deduce template arguments when using implicitly cast array literals

2021-07-23 Thread Rekel via Digitalmars-d-learn
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) {
	foo2([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.
The type of l is well known, and given the template, the type of 
R should thus be known as well. T[L1] should be deduced to 
float[4].
Did I make a mistake in the argument list? I know things like the 
order are sometimes issues, but that seems fine to me here. 
Seeing as bar functions fine (as does foo when R and right are 
removed) I'm at a loss.


Thanks you in advance!