为什么从对象构造函数调用 consteval 不是常量表达式?
我有如下所示的 consteval 函数:
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;
}
它在需要编译时值的地方按预期工作:
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;
}
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;
}
有没有办法让它工作?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不能使用
constexpr
函数的参数调用consteval
函数,因为它可能是非常量。您可以将
S::S
更改为consteval
或将text_id
更改为constexpr
。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
.