6

对另一个问题的评论中,用户 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!");

无法在编译时评估?您能否详细说明引用的评论并判断我是否正确?

4

2 回答 2

3

我在那条评论中说的是你不能有类似的东西

template <int N>
int f();

constexpr int g(int i) {
  return f<i>(); // invalid
}

因为虽然constexpr函数的结果可以是常量表达式,但在主体内部,它的参数不是。一个constexpr函数可以用常量或非常量参数调用,调用者可以决定,C++没有任何类型的函数只能用常量参数调用。

这对您正在阅读的答案很重要,因为拥有一个const char (&str)[N]函数参数并将str[i]其视为函数体内的常量表达式会很有用。

这对于您拥有的代码无关紧要。那个代码很好。

于 2014-09-18T17:57:48.037 回答
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] 中找不到任何禁止这样做的内容。

于 2014-09-18T16:20:48.803 回答