I find it very annoying that the following code results in a tuple out of bounds error message and not only the static assert message. template T(Ts...) { static assert(Ts.length > 1); alias Ts[1] Z; } void main() { alias T!(int).Z Z2; } gives wiz.d(4): Error: tuple index 1 exceeds 1 wiz.d(3): Error: static assert (1LU > 1LU) is false wiz.d(8): instantiated from here: T!(int) I think error reporting should stop at the static assert.
Workarounds: 1) ----- template T(Ts...) if (Ts.length > 1) { alias Ts[1] Z; } ----- 2) ----- template T(Ts...) { static if (Ts.length > 1) alias Ts[1] Z; else static assert(0); } -----
Today, the code yields: onlineapp.d(2): Error: tuple index 1 exceeds 1 onlineapp.d(7): Error: template instance `onlineapp.T!int` error instantiating And I am arguing that this is the correct behavior. The static assert is generally used to test that things inside the template instantiation are correct. Template constraints are used to check that the template arguments are correct. The static assert cannot be evaluated before the template is instantiated because that will make it useless in 99% of the cases. The general case for static asserts in template declarations is to check that specific template properties are correct, therefore, you first need to have the instantiation before you actually evaluate the static assert. In conclusion: use template constraints for this scenario: template T(Ts...) if (Ts.length > 1) { alias Ts[1] Z; } Closing as invalid.