I have the consteval
function shown below:
template <std::size_t text_length>
consteval std::size_t text_id(const char(&a_text)[text_length])
{
std::size_t result{text_length};
for (const auto &c : a_text)
{
result ^= c;
result <<= ((c % 7u) + 1u);
}
return result;
}
It works as expected on the places where a compile-time value is expected:
template <auto x>
auto v = x;
int main(int argc, char **argv)
{
constexpr auto id = text_id("test");
switch (argc)
{
// No problem
case text_id("test"):
std::cout << v<text_id("test")>; // No problem either
break;
}
return 0;
}
But it doesn't compile if I put it on an object constructor:
struct S
{
template <std::size_t size>
constexpr S(const char (&text)[size]) :
id{text_id(text)}
{}
std::size_t id;
};
int main()
{
/*
error: 'text' is not a constant expression
id{text_id(text)}
~~~~~~~^~~~~~
*/
constexpr S s("test");
static_assert(text_id("test") == s.id);
return 0;
}
Is there a way to make it work?
You cannot call
consteval
function withconstexpr
function's parameter, since it may be non-constant.You can change
S::S
toconsteval
or changetext_id
toconstexpr
.