首页 > 解决方案 > is_constant_evaluate() 应该产生 constexpr 变量吗?

问题描述

我已经阅读了std::is_constant_evaluated()定义,但我仍然不确定为什么 (1) 不能与最新的 GCC一起使用:error: 'x' is not a constant expression

template<auto v>
struct s
{};

constexpr void f(int x)
{
    if (std::is_constant_evaluated())
    {
        // constexpr int z=x; (1)
        // s<x> a; (2)
    }
}

int main(int argc, char* argv[])
{
    f(4);
    //f(argc);
    return 0;
}
  1. 按照标准,这应该有效吗?
  2. 还是只是 GCC 的实现有问题?
  3. 我能以某种方式实现预期的行为吗?基本上是:

随着分支std::is_constant_evaluated()

更新

我可以将 constexpr-essiveness 信息“传输”到函数中吗?基本上决定f()是否用constexprx 调用它。

更新 关于我想要实现的更复杂的示例:如果可能,此示例应在编译时对参数进行字符串化。

template<auto v>
struct dummy_stringify
{
    static constexpr auto str=v==4 ? "4" : "31"; // this is just an example; imagine here a much more complex logic
};

constexpr void f(int x)
{
    if (std::is_constant_evaluated())
    {
        std::puts("A compile time calculation:");
        //std::puts(dummy_stringify<x>::str);
    } else
    {
        std::cout<<"A runtime calculation:"<<std::endl;
        std::cout<<x<<std::endl;
    }
}
int main(int argc, char* argv[])
{
    f(4);
    f(argc);
    return 0;
}

标签: c++constexprc++20

解决方案


x不是一个常量表达式,不管它f本身是如何计算的。那是if那里的常规(如何is_constant_evaluated使用)。它不是一个废弃的分支,因此即使不是不断评估,它也必须包含格式良好f代码。当x将不是常量表达式时,该函数仍将包含该(未执行的)分支,并且它将尝试x在需要常量表达式的地方使用。这显然是不正确的。

GCC 不接受它是非常正确的。


推荐阅读