Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 10, 2015 "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Hi! I get the following compile error (linux, dmd2.066.1): test.d(13): Error: template test.testFunc cannot deduce function from argument types !()(double[], double), candidates are: test.d(3): test.testFunc(R)(R range, ElementType!R foo) For the following test file: import std.range: ElementType, isInputRange; ElementType!R testFunc(R)( R range, ElementType!R foo) // compiles with double foo { static assert( isInputRange!R ); ElementType!R retVal = foo*foo; return retVal; } void main() { double[] values = [0.0, 3.0, -1.0, 5.0]; auto result = testFunc( values, 8.8 ); } And I'm not sure what I'm doing incorrectly. It compiles/works fine if I hardcode the type for foo. Could someone enlighten me ? regards, ted |
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to ted | On 02/10/2015 12:31 AM, ted wrote: > ElementType!R testFunc(R)( R range, ElementType!R foo) // compiles with > double foo If think it is a little too much to ask from the template system of D. A proper way of doing the same thing is to use a template constraint: ElementType!R testFunc(R, E)( R range, E foo) if (is (E : ElementType!R)) Ali |
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to ted | ted:
> Could someone enlighten me ?
This works:
import std.range: ElementType, isInputRange;
ElementType!R testFunc(R, T)(R range, T foo)
if (is(ElementType!R == T)) {
static assert(isInputRange!R);
typeof(return) retVal = foo ^^ 2; // More DRY.
return retVal;
}
void main() {
auto values = [0.0, 3.0, -1.0, 5.0];
auto result = testFunc(values, 8.8);
}
The D compiler seems unable to compute ElementType!R in the function signature. If I am right, then this seems worth an enhancement request.
Bye,
bearophile
|
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli:
> If think it is a little too much to ask from the template system of D.
I remember hitting a similar problem with code like this bar() function:
// OK
void foo(size_t N1, size_t N2)(int[N1] a, int[N2] b)
if (N2 == N1 ^^ 2) {}
// Not OK
void bar(size_t N)(int[N] a, int[N ^ 2] b) {}
void main() {
int[2] a = [1, 2];
int[4] b = [1, 2, 3, 4];
foo(a, b);
bar(a, b);
}
So perhaps my suggestion to file an enhancement request is not a good idea...
Bye,
bearophile
|
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli wrote: > On 02/10/2015 12:31 AM, ted wrote: > > > ElementType!R testFunc(R)( R range, ElementType!R foo) // compiles > > with double foo > > If think it is a little too much to ask from the template system of D. A proper way of doing the same thing is to use a template constraint: > > ElementType!R testFunc(R, E)( R range, E foo) > if (is (E : ElementType!R)) > > Ali ....thanks ! |
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > void bar(size_t N)(int[N] a, int[N ^ 2] b) {}
I meant:
void bar(size_t N)(int[N] a, int[N ^^ 2] b) {}
|
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote:
> ted:
>
>> Could someone enlighten me ?
>
> This works:
>
>
> import std.range: ElementType, isInputRange;
>
> ElementType!R testFunc(R, T)(R range, T foo)
> if (is(ElementType!R == T)) {
> static assert(isInputRange!R);
> typeof(return) retVal = foo ^^ 2; // More DRY.
> return retVal;
> }
>
> void main() {
> auto values = [0.0, 3.0, -1.0, 5.0];
> auto result = testFunc(values, 8.8);
> }
>
>
> The D compiler seems unable to compute ElementType!R in the function signature. If I am right, then this seems worth an enhancement request.
>
> Bye,
> bearophile
thanks !...
... where you say 'More DRY' above, are you referring to
- foo^^2 ( I just did foo*foo for the sake of the example), or
- typeof(return) - a construct I am completely unfamiliar with and will
now have to look up !
If it is 'typeof(return)' why would this be selected over ElementType!R ?? Is it more idiomatic ?
regards,
ted
|
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to ted | ted: > ... where you say 'More DRY' above, are you referring to I was referring to both, but mostly to the typeof. It's more DRY (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself ). You are stating only once the type of the return variable. This is less bug-prone. Bye, bearophile |
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 02/10/2015 01:08 AM, bearophile wrote: > // Not OK > void bar(size_t N)(int[N] a, int[N ^^ 2] b) {} > So perhaps my suggestion to file an enhancement request is not > a good idea... I am not sure. Although the template system already does pretty clever deductions, I think they are all based on hints given by the programmer. They work "forward" from the rules. However, both in your example above and in ted's code, the compiler has to solve a problem similar to declarative programming languages to arrive at the intent. For example, it must apply sqrt to the second length to figure out N. Admittedly, it is not apparent in the code above because the first parameter is already trivially N so the human reader thinks "N comes from the first argument and it must also satisfy the second argument". The following would ask the compiler to work backward from the argument: void bar(size_t N)(int[N ^^ 2] b) {} "Take a value from the argument, take its square root and then use that value to figure out the instantiation value of this template." Ali |
February 10, 2015 Re: "cannot deduce function from argument types" issue. | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote:
> ted:
>
>> ... where you say 'More DRY' above, are you referring to
>
> I was referring to both, but mostly to the typeof. It's more DRY (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself ). You are stating only once the type of the return variable. This is less bug-prone.
>
> Bye,
> bearophile
Ha !
..more stuff to learn!
many thanks...
regards,
ted
|
Copyright © 1999-2021 by the D Language Foundation