在this comment to another question中,用户hvd声明了以下内容:
...尽管可以将字符串文字传递给
constexpr
函数, 并且在常量中的字符串文字上允许数组索引 表达式,constexpr
函数参数的索引操作 不符合常数表达式。
我并不完全明白其含义。这是否意味着以下代码中的hash_value
变量
#include <cstddef>
// Compute the hash of a string literal adding the values of its characters
template<std::size_t N> constexpr std::size_t
hash_string
( const char (& s)[N] )
noexcept
{
std::size_t h = 0;
// Array indexing happening under the hood
for ( const auto c : s )
h += c;
return h;
}
constexpr auto hash_value = hash_string("Hello, world!");
无法在编译时进行评估?你能否详细说明引用的评论并告诉我是否正确?
答案 0 :(得分:3)
我在评论中说的是你不能拥有像
这样的东西template <int N>
int f();
constexpr int g(int i) {
return f<i>(); // invalid
}
因为虽然constexpr
函数的结果可以是常量表达式,但在体内,其参数不是。可以使用常量或非常量参数调用constexpr
函数,调用者可以决定,并且C ++没有任何类型的函数,只能 使用常量参数调用
在您正在阅读的答案中,这很重要,因为拥有const char (&str)[N]
函数参数会很有用,并将str[i]
视为函数体内的常量表达式。
这与您获得的代码无关。那段代码很好。
答案 1 :(得分:2)
我浏览了N3337和N3936的相关部分,并且该标准的任何一个版本都没有禁止排序的constexpr
功能
template<std::size_t N> constexpr std::size_t
hash_string
( const char (& s)[N] )
noexcept
{
return s[0];
}
事实上,这在C ++ 11模式下编译g ++和clang。我完全不知道“对constexpr
函数参数的索引操作不符合常量表达式”的说法来自哪里。我在§5.19[expr.const]中找不到任何禁止此内容的内容。