www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template type deduction question

reply data pulverizer <data.pulverizer gmail.com> writes:
I'd like to pass kernel functions using:

```
auto calculateKernelMatrix(K, T)(K!(T) Kernel, Matrix!(T) data)
{
   ...
}

```

and call it using `calculateKernelMatrix(myKernel, myData);` but 
I get a type deduction error and have to call it using 
`calculateKernelMatrix!(typeof(myKernel), float)(myKernel, 
myData);`

How do I resolve this?
May 20 2020
parent reply Basile B. <b2.temp gmx.com> writes:
On Thursday, 21 May 2020 at 04:46:02 UTC, data pulverizer wrote:
 I'd like to pass kernel functions using:

 ```
 auto calculateKernelMatrix(K, T)(K!(T) Kernel, Matrix!(T) data)
 {
   ...
 }

 ```

 and call it using `calculateKernelMatrix(myKernel, myData);` 
 but I get a type deduction error and have to call it using 
 `calculateKernelMatrix!(typeof(myKernel), float)(myKernel, 
 myData);`

 How do I resolve this?
The problem is that "K" is a template type parameter [1]. When the compiler deduces the parameter that ends up with a symbol, i.e not a type. To permit a symbol to be deduced you can use a template alias parameter[2] instead: --- struct Matrix(T) {} struct Kernel(T) {} void calculateKernelMatrix(alias K, T)(K!T kernel, Matrix!T data) { } void main() { Matrix!float m; Kernel!float k; calculateKernelMatrix(k,m); // OK } --- However I think that there could be an useful error message, as the current one is of no usefulness. Note that maybe that under the hood there's one but the compiler uses a system of gagging when trying uncertain operations, so that other things can be tried, in case of failure. [1] https://dlang.org/spec/template.html#template_type_parameters [2] https://dlang.org/spec/template.html#aliasparameters
May 21 2020
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 21 May 2020 at 07:16:11 UTC, Basile B. wrote:
 On Thursday, 21 May 2020 at 04:46:02 UTC, data pulverizer wrote:
 I'd like to pass kernel functions using:

 ```
 auto calculateKernelMatrix(K, T)(K!(T) Kernel, Matrix!(T) data)
 {
   ...
 }

 ```

 and call it using `calculateKernelMatrix(myKernel, myData);` 
 but I get a type deduction error and have to call it using 
 `calculateKernelMatrix!(typeof(myKernel), float)(myKernel, 
 myData);`

 How do I resolve this?
The problem is that "K" is a template type parameter [1]. When the compiler deduces the parameter that ends up with a symbol, i.e not a type. To permit a symbol to be deduced you can use a template alias parameter[2] instead: --- struct Matrix(T) {} struct Kernel(T) {} void calculateKernelMatrix(alias K, T)(K!T kernel, Matrix!T data) { } void main() { Matrix!float m; Kernel!float k; calculateKernelMatrix(k,m); // OK } --- However I think that there could be an useful error message, as the current one is of no usefulness. Note that maybe that under the hood there's one but the compiler uses a system of gagging when trying uncertain operations, so that other things can be tried, in case of failure. [1] https://dlang.org/spec/template.html#template_type_parameters [2] https://dlang.org/spec/template.html#aliasparameters
I've found that even with a template constraint the diagnostic is sub-optimal, see issue 20851 [1]. [1] https://issues.dlang.org/show_bug.cgi?id=20851
May 21 2020
prev sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 21 May 2020 at 07:16:11 UTC, Basile B. wrote:
 The problem is that "K" is a template type parameter [1].
 When the compiler deduces the parameter that ends up with a 
 symbol, i.e not a type.
 To permit a symbol to be deduced you can use a template alias 
 parameter[2] instead:

 ---
 struct Matrix(T) {}
 struct Kernel(T) {}

 void calculateKernelMatrix(alias K, T)(K!T kernel, Matrix!T 
 data) { }

 void main()
 {
     Matrix!float m;
     Kernel!float k;
     calculateKernelMatrix(k,m); // OK
 }
 ---
Thanks!
May 21 2020