digitalmars.D - resolving template instantiations
- Christian Kamm (44/44) Jun 30 2009 I started out wanting to document implicit function template instantiati...
- Paul D. Anderson (5/11) Jul 01 2009 Have you entered this into Bugzilla to keep your list of spec issues cur...
- Christian Kamm (7/9) Jul 02 2009 No, I haven't yet. I was hoping to get an explanation for DMD's behavior...
I started out wanting to document implicit function template instantiation
(IFTI) and type deduction and ended up reading the DMD frontend code for
template instantiation. There I discovered that choosing the correct
template declaration involves more logic than the spec indicates.
The specification says that if a template instantiation has an argument list
that fits more than one template declaration, the most specialized
declaration is chosen. If the declarations are equally specialized or there
is no such order, an error is raised. Determining which declaration is more
specialized is done in a way inherited from C++: if the first declaration
could be instantiated with any argument list that's valid for the second,
the first is equally or less specialized than the second.
In the DMD frontend though, there's another factor that eliminates some
candidates before the ordering criterion is applied: each template
declaration matches the template argument list either exactly or with
conversions (similar to function overloads). If there is at least one exact
match, the most specialized declaration is chosen among the exact matches.
Only if there are no exact matches is the ordering criterion used to find
the most specialized among the matches-with-conversion.
It gets interesting when you throw in the fact that template type parameters
without specialization will generally be considered to be match-with-
conversion only (a comment states: "so that matches with specializations are
better"). For instance
template Foo1(T) { pragma(msg, "type"); }
template Foo1(alias T) { pragma(msg, "alias"); }
alias Foo1!(Object) f1; // alias (type is only match-with-conversions)
but
template Foo2(T : Object) { pragma(msg, "type"); }
template Foo2(alias T) { pragma(msg, "alias"); }
alias Foo2!(Object) f2; // type (both match exactly, type is more
specialized)
(the same works with a tuple parameter instead of the alias parameter).
It's easy to see that for value parameters looking at the match quality is a
good idea
template Bar1(int i) { pragma(msg, "int"); }
template Bar1(uint i) { pragma(msg, "uint"); }
alias Bar1!(42) b1; // int (uint only matches with conversions)
as the template instantiation would be ambiguous otherwise - neither
declaration is more specialized than the other.
Is this intended behavior? If so, what's the rationale for checking the
match quality for non-value parameters? Is there a case where mere template
ordering would produce inferior results with type parameters?
If it is intended, let's document and explain it in the specification. If it
isn't, it needs to be changed or removed before the D2 freeze makes code
into law.
Jun 30 2009
Christian Kamm Wrote:<snip/>If it is intended, let's document and explain it in the specification. If it isn't, it needs to be changed or removed before the D2 freeze makes code into law.Have you entered this into Bugzilla to keep your list of spec issues current? Thanks for doing that, by the way. :-) Paul
Jul 01 2009
Paul D. Anderson wrote:Have you entered this into Bugzilla to keep your list of spec issues current?No, I haven't yet. I was hoping to get an explanation for DMD's behavior from Walter, maybe even a discussion about the correct way to select template declarations and whether ordering by specialization is even still needed when you have template constraints. But I will make sure the issues get a Bugzilla entry if they can't be resolved directly.
Jul 02 2009








Christian Kamm <kamm-incasoftware removethis.de>