为什么从对象构造函数调用 consteval 不是常量表达式?

发布于 2025-01-15 04:16:37 字数 2635 浏览 2 评论 0原文

我有如下所示的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

养猫人 2025-01-22 04:16:37

您不能使用 constexpr 函数的参数调用 consteval 函数,因为它可能是非常量。

consteval int bar(int){
    return 1;
}

constexpr int foo(int s){
    return bar(s); // error
}

您可以将 S::S 更改为 consteval 或将 text_id 更改为 constexpr

You cannot call consteval function with constexpr function's parameter, since it may be non-constant.

consteval int bar(int){
    return 1;
}

constexpr int foo(int s){
    return bar(s); // error
}

You can change S::S to consteval or change text_id to constexpr.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文