Comment #0 by destructionator — 2021-02-18T03:51:11Z
https://dlang.org/spec/template.html#template_value_parameter
"Template value parameter types can be any type which can be statically initialized at compile time."
So far, this ought to allow classes since they can be statically initialized at compile time! And indeed, the compiler lets me write the parameter.
---
template test(Object o) { } // compiles fine
---
However, the spec then says:
"Template value arguments can be integer values, floating point values, nulls, string values, array literals of template value arguments, associative array literals of template value arguments, or struct literals of template value arguments."
Which makes that definition useless since it is impossible to actually pass an argument to that template!
---
void main() { test!(new Object); } // rejected!
---
There's no justification for this ever since classes were implemented in CTFE. Indeed, the compiler does allow me to write:
---
template test(Object[] o) { enum test = 0; }
void main() { int dummy = test!([new Object]); }
---
without complaint! So wrapping it in an array is fine (this is technically accepts-invalid since [new Object] is not an array of template value arguments, but the error is not diagnosed until codegen which means you can smuggle the value in if you keep it strictly in a CTFE context, but since you can initialize static object arrays in CTFE for runtime without error, even this seems silly). But the compiler rejects the immediate object out of hand.
I don't see any reason for this restriction to continue to exist. I can understand it not accepting a reference since that cannot be read at compile time and mutable aliases and CTFE are not likely to work well anyway.
But is there a good reason not to allow an object literal?
Comment #1 by destructionator — 2021-02-18T03:58:48Z
I suspect the reason has to do with mangling the class values, but it isn't that different than a struct, so I don't think it is fundamentally problematic.
Another related problem is that `enum Object o = new Object;` is not allowed, since then you'd have questions of Object aliasing at runtime (arrays are arguably similar but they solve it by reallocating for each use, so perhaps a class could do that too, but I also don't think this is required at all since a template can just use it at CTFE then export it as `static` instead of `enum`).
Comment #2 by robert.schadek — 2024-12-13T19:14:45Z