template Boo(T) {} struct Foo(T, alias V = Boo!T) { pragma(msg, V.stringof); } alias Foo!double B; alias Foo!int A; outputs Boo!(double) Boo!(double) while it should Boo!(double) Boo!(int) Although it's a blocker for a design that I intend to use, I don't mark it as such with hope that it'll get fixed, as it looks trivial to me.
This is caused as default arguments to templates are only instantiated once, which causes the Boo!T to always become whatever is instantiated first. The patch below fixes this: --- template.c 2010-03-18 18:58:06.000000000 +0000 +++ template.c 2010-04-23 20:49:54.000000000 +0100 @@ -2993,6 +2993,17 @@ Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc) { + Type *ta = isType(defaultAlias); + if (ta) + { + if (ta->ty == Tinstance) + { + // If the default arg is a template, instantiate for each type + Object *da = ta->syntaxCopy(); + Object *o = aliasParameterSemantic(loc, sc, da); + return o; + } + } Object *o = aliasParameterSemantic(loc, sc, defaultAlias); return o; }
changelog 492
This problem still exists, if the default expression is not a type, but an actual expression referring to a type: template Tpl(T, alias S = "" ~ T.stringof) { pragma(msg, S); } class A { } class B { } alias TA = Tpl!A; alias TB = Tpl!B; I think a possible solution would be to always use a syntaxCopy() of defaultAlias. How would this affect performance?
*** This issue has been marked as a duplicate of issue 22540 ***