#dbugfix Issue 16486 200$
Simen Kjærås
simen.kjaras at gmail.com
Sat Mar 31 16:34:14 UTC 2018
On Saturday, 31 March 2018 at 13:34:18 UTC, Kagamin wrote:
> On Friday, 30 March 2018 at 13:56:45 UTC, Stefan Koch wrote:
>> Ah that is an interesting bug which further demonstrates that
>> templates are a tricky thing :)
>> Basically you cannot _generally_ proof that one template just
>> forwards to another.
>> Therefore you have to create separate types.
>> And since you create separate types the alias is not an alias
>> but a separate template.
>> Solving this may be possible for special cases but in the
>> general case is infeasible.
>
> If a template is used as a type it should be resolved to a
> type, no? And template resolves to a type in a straightforward
> way. Where does it fail? Judging by the error message "cannot
> deduce function from argument types !()(TestType!int)" it does
> successfully resolve alias to a type.
You're starting in the wrong end - the type cannot yet be
considered, since the compiler doesn't know the correct arguments
to TestAlias. Given this code:
struct S(T...) {}
alias SS(T...) = S!(T, int);
void foo(T)(SS!T arg) {}
unittest {
foo(SS!string());
}
The error message is "template foo cannot deduce function from
argument types !()(S!(string, int)), candidates are: foo(T)(SS!T
arg)".
What the compiler needs to do is figure out what T needs to be in
order for SS to return the type S!(int, int). SS hasn't resolved
to a type yet at that point, because the compiler has no idea
which arguments to give it.
These are the steps the compiler does when it evaluates a
function call (simplified):
1) Figure out the overload set.
2) Weed out non-matching overloads.
3) Check that exactly one overload matches*.
4) Use that overload.
In step 2, the compiler looks at the types when the overload is a
regular function. When it's a function template, it doesn't know
the types yet, and IFTI tries to figure it out by a sort of
pattern matching. In the case above, it doesn't find a
S!(/*something*/) anywhere, and gives up.
If the compiler were to do something other than give up, we would
need some algorithm to define what it should try, and in which
order. As human beings, with impressive collections of
pattern-matching circuits, we can easily see that it should try
putting the first template argument into T. Getting to that
conclusion is a lot harder for the poor, stupid compiler.
--
Simen
*In the case where multiple overloads are a match, the best fit
is chosen. If there's more than one best fit, or there's no
match, you get a compile error.
More information about the Digitalmars-d
mailing list