首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::is_constant_evaluated行为

std::is_constant_evaluated行为
EN

Stack Overflow用户
提问于 2019-01-18 09:59:37
回答 2查看 2.5K关注 0票数 25

GCC9已经实现了std::is_constant_evaluated。我玩了一点,我意识到这有点棘手。这是我的测试:

代码语言:javascript
复制
constexpr int Fn1()
{
  if constexpr (std::is_constant_evaluated())
    return 0;
  else
    return 1;
}

constexpr int Fn2()
{
  if (std::is_constant_evaluated())
    return 0;
  else
    return 1;
}

int main()
{
  constexpr int test1 = Fn1(); // Evaluates to 0
  int test2 = Fn1();           // Evaluates to 0
  int const test3 = Fn1();     // Evaluates to 0

  constexpr int test4 = Fn2(); // Evaluates to 0
  int test5 = Fn2();           // Evaluates to 1
  int const test6 = Fn2();     // Evaluates to 0
}

根据这些结果,我得出了以下结论:

  • if constexpr (std::is_constant_evaluated())总是计算true分支。因此,使用这种结构是没有意义的。
  • 如果编译器在编译时计算一个变量,则std::is_constant_evaluated())true,无论该变量是否显式注释constexpr

我说的对吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-18 10:09:43

if constexpr需要条件的常量表达式。因此,在这种情况下,is_constant_evaluated当然总是正确的。

这是为了一个普通的if。其目的是不进入在constexpr函数中在常量表达式中求值时非法的代码路径。而是让它在运行时执行。它并不是要从函数中完全消除这些代码路径。

票数 19
EN

Stack Overflow用户

发布于 2019-01-18 15:27:13

我是这么想的,也许你会觉得这很有帮助.也许不会。请注意,我认为编写if constexpr (std::is_constant_evaluated())是一个非常常见的错误,这是一个很容易陷入的陷阱。但希望编译器能够诊断出这种情况。提交的91428,这是固定gcc 10.1。

我们本质上有两种不同的代码规则--正常运行时代码的典型规则,以及用于constexpr编程的常量表达式的限制。这些都是expr.const的限制:没有UB,没有reinterpret_cast等,这些限制从语言标准到语言标准不断减少,这是很好的。

基本上,控制流(从代码路径的角度来看)在“完全运行时”模式和constexpr模式之间交替进行。一旦我们进入constexpr模式(无论是通过初始化constexpr对象或计算模板参数或.),我们将一直呆在那里直到完成.然后我们又回到了完全运行模式。

is_constant_evaluated()所做的只是简单地说:我是否处于固定模式?它告诉您,如果您所处的上下文需要常量表达式。

在这个视图中,让我们看看if constexpr (is_constant_evaluated())。无论我们过去处于何种状态,if constexpr都需要一个常量表达式作为初始化,因此如果我们还没有在那里,这就会将我们提升到constexpr模式。因此,is_constant_evaluated()是真的--无条件的。

但是,对于if (is_constant_evaluated()),一个简单的if并不会在运行时和运行时之间改变我们的状态。因此,这里的值取决于从哪个上下文调用的。初始化test4会使我们进入constexpr模式,因为它是一个constexpr对象。在初始化过程中,我们遵循常量表达式规则.所以is_constant_evaluated()是真的。但一旦我们完成了我们又回到了运行规则..。因此,在test5的初始化中,is_constant_evaluated()是假的。(然后,test6是一种不幸的语言特例--您可以使用常量积分变量作为常量表达式,因此我们以相同的方式处理它们的初始化。)

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54251530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档