Проблема с функциями constexpr заключается в том, что вы можете вызывать как с аргументами constexpr, так и с аргументами non-constexpr:
int constexpr f(int n)
{
return ++n;
}
int constexpr n0 = 7;
int n1; std::cin >> n1;
f(n0); // result IS constexpr
f(n1); // result is NOT constexpr, just an ordinary int
Из-за этой характеристики сами параметры функции не могут быть constexpr, или, точнее, не может использоваться в контекстах constexpr. Так и в вашей функции:
constexpr size_t arraySize = getSize(format);
// ^ cannot be used as constexpr, even if
// constexpr has been passed to, so result
// not either (the f(n1) case above)
Вы можете немного изменить свою вторую функцию:
template <size_t Size>
constexpr auto
getArray()
{
return std::array<char, Size>();
}
И использовать ее как
int main(int argc, char** argv)
{
static_assert(getArray<getSize("hello")>().size() == 0, "failed");
return 0;
}
Конечно, выглядитдовольно уродливо, но вы можете спрятаться за макросом:
#define myGetArray(STRING) getArray<getSize(STRING)>()
или просто
#define getArray(STRING) std::array<char, getSize(STRING)>()