为什么 char 数组可以在 constexpr 函数模板中使用,但不能在 static_assert 中使用

Ste*_*mer 5 c++ templates static-assert

我有一个constexpr函数模板,它采用一个char数组,其边界在编译时已知:

\n\n
template<size_t N>\nconstexpr bool check(const char (&arr)[N], size_t n = 0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我可以在调用中将此函数与字符串文字一起使用static_assert

\n\n

在此函数中,我可以遍历字符串文字,并在编译时对组成字符串的各个字符执行计算。

\n\n

但是,如果我有另一个constexpr也采用字符数组/字符串文字的函数模板

\n\n
template<size_t N>\nconstexpr void test(const char (&arr)[N])\n
Run Code Online (Sandbox Code Playgroud)\n\n

在我调用的函数中static_assertarr不再是常量表达式,因此static_assert不允许使用 。

\n\n

鉴于字符串文字的边界在编译时已知,因此它是一个静态大小的数组,并且size_t N是一个模板参数,我认为它应该可以arr在 function 中使用test

\n\n

不可能test使用非常量数组进行调用,因此我希望编译器arr知道test.

\n\n

尝试test使用非常量数组进行调用会导致不同的(预期)错误:

\n\n
main.cpp:16:16: note:   template argument deduction/substitution failed:\nmain.cpp:32:15: note:   mismatched types \xe2\x80\x98const char [N]\xe2\x80\x99 and \xe2\x80\x98const char*\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n\n

问题:

\n\n

为什么我可以在aconst char (&arr)[N] 内部static_assert使用,但不能将其传递a static_assert

\n\n

完整示例:

\n\n
#include <cstddef>\n#include <stdexcept>\n\ntemplate<size_t N>\nconstexpr bool check(const char (&arr)[N], size_t n = 0)\n{\n    return\n        n >= N ?\n            true\n        : arr[n] != \'*\' ?\n            check(arr, n + 1)\n        : throw std::logic_error("arr can\'t contain a \'*\'");\n}\n\ntemplate<size_t N>\nconstexpr void test(const char (&arr)[N])\n{\n    static_assert(check<N>(arr), ""); // non-constant condition for static assertion\n}\n\nint main()\n{\n    static_assert(check("foo"), "");\n\n    // fails to compile: string contains \'*\'\n    //static_assert(check("foo*"), ""); \n\n    // fails to compile: \xe2\x80\x98arr\xe2\x80\x99 is not a constant expression\n    //test("foo"); \n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n