Thread overview | ||||||
---|---|---|---|---|---|---|
|
June 14, 2016 how to get rid of "cannot deduce function from argument types" elegantly | ||||
---|---|---|---|---|
| ||||
I made a small (could be reduced further) example that creates and walks a templated binary tree. The tree also gets a factory function to use type deduction to conveniently construct a tree. Unfortunately this does not compile, if I remove the three ugly methods between /* these should go */ comments. ``` fibertest.d(49): Error: template fibertest.tree cannot deduce function from argument types !()(int, typeof(null), typeof(null)), candidates are: fibertest.d(41): fibertest.tree(T)(T node, Tree!T left, Tree!T right) ``` Is there a more elegant way to fix this? Another fix would be to provide 4 factory functions like this (still not really nice): ``` tree(Tree!T left, T node, Tree!T right) {...} tree(T node, Tree!T right) {...} tree(Tree!T left, T node) {...} tree(T node) {...} ``` ```d import std.concurrency, std.stdio, std.range; class Tree(T) { Tree!T left; T node; Tree!T right; this(Tree!T left, T node, Tree!T right) { this.left = left; this.node = node; this.right = right; } auto inorder() { return new Generator!T(() => yieldAll(this)); } private void yieldAll(Tree!T t) { if (t is null) return; yieldAll(t.left); yield(t.node); yieldAll(t.right); } } /* these should go */ Tree!T tree(T)(typeof(null) left, T node, typeof(null) right) { return new Tree!T(null, node, null); } Tree!T tree(T)(Tree!T left, T node, typeof(null) right) { return new Tree!T(left, node, null); } Tree!T tree(T)(typeof(null) left, T node, Tree!T right) { return new Tree!T(null, node, right); } /* these should go */ Tree!T tree(T)(Tree!T left, T node, Tree!T right) { return new Tree!T(left, node, right); } void main(string[] args) { // /3 // /2 // 1 auto t1 = tree(tree(tree(null, 1, null), 2, null), 3, null); // 1 // \2 // \3 auto t2 = tree(null, 1, tree(null, 2, tree(null, 3, null))); writeln(t1.inorder()); writeln(t2.inorder()); writeln(t1.inorder().array == t2.inorder().array); } ``` |
June 13, 2016 Re: how to get rid of "cannot deduce function from argument types" elegantly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christian Köstlin | On 06/13/2016 03:30 PM, Christian Köstlin wrote:
> Tree!T tree(T)(Tree!T left, T node, Tree!T right) {
> return new Tree!T(left, node, right);
> }
This works but I don't know whether it's a bug or not:
Tree!T tree(TT, T)(TT left, T node, TT right) {
return new Tree!T(left, node, right);
}
Perhaps this is better:
Tree!T tree(TL, T, TR)(TL left, T node, TR right) {
return new Tree!T(left, node, right);
}
Ali
|
June 14, 2016 Re: how to get rid of "cannot deduce function from argument types" elegantly | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 13 June 2016 at 22:54:13 UTC, Ali Çehreli wrote:
> Tree!T tree(TL, T, TR)(TL left, T node, TR right) {
> return new Tree!T(left, node, right);
> }
>
There's also this:
Tree!T tree(TL, T, TR)(TL left, T node, TR right) if(
(is(TL == Tree!T) || is(TL == typeof(null))) &&
(is(TR == Tree!T) || is(TR == typeof(null)))
){
return new Tree!T(left, node, right);
}
|
June 14, 2016 Re: how to get rid of "cannot deduce function from argument types" elegantly | ||||
---|---|---|---|---|
| ||||
Posted in reply to pineapple | On 6/14/16 6:05 AM, pineapple wrote:
> On Monday, 13 June 2016 at 22:54:13 UTC, Ali Çehreli wrote:
>> Tree!T tree(TL, T, TR)(TL left, T node, TR right) {
>> return new Tree!T(left, node, right);
>> }
>>
>
> There's also this:
>
> Tree!T tree(TL, T, TR)(TL left, T node, TR right) if(
> (is(TL == Tree!T) || is(TL == typeof(null))) &&
> (is(TR == Tree!T) || is(TR == typeof(null)))
Alternative: if(is(typeof({Tree!T x = TL.init; x = TR.init; })))
This may seem similar, but actually can accept things that convert to Tree!T as well.
The issue with the OP code is that the compiler is trying to match T with the two null parameters, and can't work out the deduction.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation