Function parameters in `constexpr` functions aren't constexpr; only non-type template parameters are considered constant expressions. However, you can approximate `constexpr` parameters through the use of a type:
template<size_t N>
constexpr auto func(std::integral_constant_t<size_t, N>)
{
return std::array<int, N>{};
}
The problem with this is that you have to invoke such a function in a very unnatural way: `func(std::integral_constant<std::size_t, 20>);` That puts a lot of noise in the function argument, when what you really want to say is `func(20);`
What I suggest is making `integral_constant` specially recognized by the compiler in template argument deduction circumstances. If the given argument for such a parameter is either an integer literal (with a non-narrowing conversion to the `integral_constant`'s type) or a constexpr variable (who's type has a non-narrowing conversion to the `integral_constant`'s type), then the compiler will deduce the corresponding `N` as if you had spelled out `std::integral_constant_t<typename>`. If the type of `integral_constant` is also deduced (either via C++17's `auto` or as a template parameter), then this would work as well, simply using the type of the expression.
We could also add more `type_constant` types to the standard library, like `float_constant`, `pointer_constant`, etc.
One reason I bring this up is that this feels like it's really a part of a more generic feature, but I can't think of what such a feature might look like. This looks like some mechanism for customizing how template argument deduction works, but what would that actually be?