В этот комментарий к другому вопросу, пользователь 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!");
нельзя оценить во время компиляции? Не могли бы вы уточнить цитируемый комментарий и сказать, прав ли я?
В этом комментарии я говорил, что нельзя
template <int N>
int f();
constexpr int g(int i) {
return f<i>(); // invalid
}
потому что хотя результат constexpr
Функция может быть константным выражением, внутри тела ее параметры не являются. constexpr
функция может вызываться с постоянными или с непостоянными аргументами, вызывающий объект принимает решение, и C ++ не имеет функции, которая может только вызываться с постоянными аргументами.
Это имело значение в ответе, который вы читали, потому что было бы полезно иметь const char (&str)[N]
аргумент функции и лечить str[i]
как постоянное выражение внутри тела функции.
Это не имеет значения для кода, который вы получили. Этот код в порядке.
Я прошел соответствующие разделы как N3337, так и N3936, и ничто в обеих версиях стандарта не запрещает constexpr
функция рода
template<std::size_t N> constexpr std::size_t
hash_string
( const char (& s)[N] )
noexcept
{
return s[0];
}
И на самом деле это компилируется как в g ++, так и в clang в режиме C ++ 11. Я понятия не имею, где утверждают, что «операция индексации на constexpr
Параметр функции не квалифицируется как «константное выражение». Я не могу найти ничего в §5.19 [expr.const], который запрещает это.