Thread overview
Template argument deduction
Mar 01, 2011
Tom
Mar 01, 2011
Ali Çehreli
Mar 01, 2011
bearophile
Mar 01, 2011
Ali Çehreli
Mar 02, 2011
Tom
March 01, 2011
I have...

import std.stdio;

int main(string[] args) {
	foo([[1,2],[3,4],[5,6]]); // ERROR [1]
	bar([[1,2],[3,4],[5,6]]); // OK
	foo!int([[1,2],[3,4],[5,6]]); // OK

	return 0;
}

void foo(T)(T[2][] t) {
	writeln(typeid(t));
}

void bar(T)(T[][] t) {
	writeln(typeid(t));
}

[1]
src\main.d(4): Error: template main.foo(T) does not match any function template declaration
src\main.d(4): Error: template main.foo(T) cannot deduce template function from argument types !()(int[][])


Why can't compiler deduce template parameters from arguments in the first instantiation?

Thanks in advance,
Tom;
March 01, 2011
On 02/28/2011 07:39 PM, Tom wrote:
> I have...
>
> import std.stdio;
>
> int main(string[] args) {
> foo([[1,2],[3,4],[5,6]]); // ERROR [1]
> bar([[1,2],[3,4],[5,6]]); // OK
> foo!int([[1,2],[3,4],[5,6]]); // OK
>
> return 0;
> }
>
> void foo(T)(T[2][] t) {
> writeln(typeid(t));
> }
>
> void bar(T)(T[][] t) {
> writeln(typeid(t));
> }
>
> [1]
> src\main.d(4): Error: template main.foo(T) does not match any function
> template declaration
> src\main.d(4): Error: template main.foo(T) cannot deduce template
> function from argument types !()(int[][])
>
>
> Why can't compiler deduce template parameters from arguments in the
> first instantiation?
>
> Thanks in advance,
> Tom;

That's because the type of literals like [1, 2] are slices (dynamic arrays), not fixed-sized arrays.

import std.stdio;

void main()
{
    writeln(typeof([1,2]).stringof);
}

The output of that program is

int[]

Ali

March 01, 2011
Ali Çehreli:

> That's because the type of literals like [1, 2] are slices (dynamic arrays), not fixed-sized arrays.

Then why is this accepted?

foo!int([[1,2],[3,4],[5,6]]); // OK

Bye,
bearophile
March 01, 2011
On 02/28/2011 07:39 PM, Tom wrote:

> foo([[1,2],[3,4],[5,6]]); // ERROR [1]
> bar([[1,2],[3,4],[5,6]]); // OK
> foo!int([[1,2],[3,4],[5,6]]); // OK

...

> void foo(T)(T[2][] t) {
> writeln(typeid(t));
> }
>
> void bar(T)(T[][] t) {
> writeln(typeid(t));
> }

On 03/01/2011 04:30 AM, bearophile wrote:

> Ali Çehreli:
>
>> That's because the type of literals like [1, 2] are slices (dynamic
>> arrays), not fixed-sized arrays.
>
> Then why is this accepted?
>
> foo!int([[1,2],[3,4],[5,6]]); // OK

If I have to guess, I think supplying T as int now becomes a problem of matching [1,2] with int[2] and it already works:

    int[2] a = [1, 2];
    int[2][] b = [ [1, 2] ];

I don't know whether the compiler should go the extra mile and help Tom in the original case. :-/

Ali

March 02, 2011
El 01/03/2011 16:05, Ali Çehreli escribió:
> On 02/28/2011 07:39 PM, Tom wrote:
>
>  > foo([[1,2],[3,4],[5,6]]); // ERROR [1]
>  > bar([[1,2],[3,4],[5,6]]); // OK
>  > foo!int([[1,2],[3,4],[5,6]]); // OK
>
> ...
>
>  > void foo(T)(T[2][] t) {
>  > writeln(typeid(t));
>  > }
>  >
>  > void bar(T)(T[][] t) {
>  > writeln(typeid(t));
>  > }
>
> On 03/01/2011 04:30 AM, bearophile wrote:
>
>  > Ali Çehreli:
>  >
>  >> That's because the type of literals like [1, 2] are slices (dynamic
>  >> arrays), not fixed-sized arrays.
>  >
>  > Then why is this accepted?
>  >
>  > foo!int([[1,2],[3,4],[5,6]]); // OK
>
> If I have to guess, I think supplying T as int now becomes a problem of
> matching [1,2] with int[2] and it already works:
>
> int[2] a = [1, 2];
> int[2][] b = [ [1, 2] ];
>
> I don't know whether the compiler should go the extra mile and help Tom
> in the original case. :-/
>
> Ali
>

I should post on D newsgroup. Perhaps Walter or Andrei could enlight us about this.

Thanks,
Tom;