Bug 18558 – Template alias spec incomplete

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dlang.org
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-03-05T15:45:19Z
Last change time
2018-06-17T05:54:02Z
Keywords
pull
Assigned to
No Owner
Creator
Jonathan Marler

Comments

Comment #0 by johnnymarler — 2018-03-05T15:45:19Z
https://dlang.org/spec/template.html#TemplateAliasParameter [Copied from spec] Alias parameters enable templates to be parameterized with almost any kind of D symbol, including user-defined type names, global names, local names, module names, template names, and template instance names. Literals can also be used as arguments to alias parameters. I've found that you can also pass function calls, i.e. ---------------------------- template Foo(alias x) { enum Foo = x; } size_t return42() { return 42; } void main() { auto foo2 = Foo!(return42()); pragma(msg, typeof(foo2).stringof); } ---------------------------- The spec should be updated to describe the true capabilities of alias template parameters. It sounds like along with symbols and literals, alias parameters can also accept compile-time values.
Comment #1 by johnnymarler — 2018-03-05T15:51:08Z
Quick clarification. Based on the example in the comment above, the following: Foo!return42 treats the `return42` part as a function call with no arguments instead of passing the `return42` symbol to the Foo template. Note that this is still true even if return42 takes arguments, it will treat it as an erroneous function call.
Comment #2 by ag0aep6g — 2018-03-05T16:02:31Z
(In reply to Jonathan Marler from comment #1) > Based on the example in the comment above, the following: > > Foo!return42 > > treats the `return42` part as a function call with no arguments instead of > passing the `return42` symbol to the Foo template. Note that this is still > true even if return42 takes arguments, it will treat it as an erroneous > function call. No. At that point it's an alias of the function. It gets called inside `Foo`: ---- template Foo(alias x) { enum Foo = x; /* This calls x. */ } ----
Comment #3 by johnnymarler — 2018-03-05T16:17:58Z
> No. At that point it's an alias of the function. It gets called inside `Foo`: Ah I see you're right. If I add pragma(msg, typeof(x)) inside the template, it shows that x is a function (not just a uint). If I change it to: Foo!(return42()) Then x will actually be a uint. Going a bit further, it looks like alias parameters do accept function calls, but in that case the function call is evaluated outside the template, as demonstrated by this example: template Foo(alias x) { pragma(msg, typeof(x)); enum Foo = x; } int return42a() { return 42; } int return42b() { return 42; } void main() { auto foo1 = Foo!(return42a()); auto foo2 = Foo!(return42b()); auto foo3 = Foo!(42); } If you compile this, the template Foo only gets instantiated once meaning that all 3 of these templates are the same. Another interesting use case, it looks like you can also use expressions, i.e. auto foo4 = Foo!(40 + 2);
Comment #4 by johnnymarler — 2018-03-05T16:26:32Z
Maybe a better description... template "alias" parameters can accept "symbols" and "values". If a symbol is passed to the template, i.e. MyTemplate!someSymbol Then the symbol is passed directly to the template without being treated as an expression to evaluate. Even if the symbol is a function, the function is not called and then passed to the template, the function symbol is passed to it. However, if an "non-symbol" expression is passed to the template, then the expression is evaluated at "compile time" and the return value passed to it, i.e. MyTemplate!42 MyTemplate!(40 + 2) enum x = 40; MyTemplate!(x + 2) auto return42() { return 42; } MyTemplate!(return42()) All these represent the same template instantiation.
Comment #5 by github-bugzilla — 2018-06-17T05:54:01Z
Commits pushed to master at https://github.com/dlang/dlang.org https://github.com/dlang/dlang.org/commit/9c53bdc77ba51f30ca3170aa02484ddd0e9ce3ef Fix Issue 18558 - Template alias spec incomplete https://github.com/dlang/dlang.org/commit/d2e6f38fe8300cf23ae52c943d9a33a4f9a1448c Merge pull request #2382 from ntrel/alias-val Fix Issue 18558 - Template alias spec incomplete