www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template argument deduction

reply Tom <tom nospam.com> writes:
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;
Feb 28 2011
parent reply =?ISO-8859-1?Q?Ali_=C7ehreli?= <acehreli yahoo.com> writes:
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
Feb 28 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
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
Mar 01 2011
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Mar 01 2011
parent Tom <tom nospam.com> writes:
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;
Mar 02 2011