From Β§8.3.4 [dcl.array] / 1:
If the constant expression (5.19), it must be a converted constant expression of the type std :: size_t, and its value must be greater than zero. The constant expression defines the boundary (number of elements) of the array
Type std::size_t .
The reason other types work in general is because conversions are performed according to the type passed in accordance with Β§14.3.2 [temp.arg.nontype] / 5:
For a template template that is not a type of an integral or enumerated type, the transformations allowed in the transformed constant expression (5.19) are applied.
From Β§5.19 [expr.const] / 3:
An integral constant expression is an expression of an integral or non-enumerated type of enumeration implicitly converted to prvalue, where the converted expression is an expression of a constant constant.
snip (mentions that they can be used as array boundaries)
A converted constant expression of type T is an expression implicitly converted to a prvalue of type T, where the converted expression is an expression of a constant constant, and the implicit conversion sequence contains only user-defined transformations, lvalue-to-rvalue transforms (4.1), integral advancements (4.5) and integral conversions (4.7), except for narrowing conversions (8.5.4).
Finally, Β§4.7 [conv.integral] / 3:
If the destination type is signed, the value does not change if it can be represented in the destination type (and bit width); otherwise, the value is determined by the implementation.
If the binding value is placed inside your parameter type, it will be successfully converted. If not, you will end up with a specific value for the binding.
Arrays are a special case, as stated in ectamur's answer :
Β§14.8.2.5 [temp.deduct.type] / 17:
If, in a function template declaration with a non-character parameter template, a non-type parameter parameter is used in the expression in the function parameter list and, if the corresponding argument template is output, the template template type must exactly match the parameter template type, except that the argument is the template deduced from the array binding can be of any integral type.