met*_*fox 17 c++ constexpr c++20 if-constexpr
GCC9已经实施std::is_constant_evaluated.我玩了一点,我意识到这有点棘手.这是我的测试:
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
}
Run Code Online (Sandbox Code Playgroud)
根据这些结果,我得出以下结论:
if constexpr (std::is_constant_evaluated())总是评估
true分支.因此,使用这种结构是没有意义的.
如果编译器在编译时评估变量,
std::is_constant_evaluated())则true无论该变量是否明确注释constexpr.
我对吗?
Sto*_*ica 13
if constexpr需要一个条件的常量表达式.因此is_constant_evaluated,在这样的背景下,当然总会如此.
这是一个常规的意思if.目的是constexpr在常量表达式中求值时,不要进入函数中非法的代码路径.但是让它在运行时执行.它不是完全消除函数中的那些代码路径.
Bar*_*rry 12
这是我对此的看法,也许你会发现这有用......也许不是.请注意,我认为写作if constexpr (std::is_constant_evaluated())将是一个非常常见的错误,并且它很容易陷入陷阱.但希望编译器能够诊断出这种情况.
我们基本上有两个不同的代码规则 - 正常运行时代码的典型规则,以及用于constexpr编程的常量表达式的限制.这些是expr.const限制:没有UB,没有reinterpret_cast等等.这些限制从语言标准到语言标准不断降低,这很好.
基本上,控制流(从代码路径的角度来看)在处于"完全运行时"模式和constexpr模式之间交替.一旦我们进入constexpr模式(无论是通过初始化constexpr对象还是评估模板参数或......),我们都会待在那里直到我们完成...然后我们又回到完全运行时模式.
什么is_constant_evaluated()做无非是:我是在constexpr模式?它告诉您是否在需要常量表达式的上下文中.
在那个视图中,让我们来看看if constexpr (is_constant_evaluated()).无论我们过去处于什么状态,都if constexpr需要一个常量表达式作为其初始化,所以如果我们不在那里,这会将我们提升到constexpr模式.因此,这is_constant_evaluated()是真的 - 无条件.
但是,对于if (is_constant_evaluated()),简单if不会改变运行时和constexpr之间的状态.所以这里的值取决于调用它的上下文.初始化test4将我们置于constexpr模式,因为它是constexpr对象.在初始化期间,我们遵循常量表达式规则......所以is_constant_evaluated()是真的.但是一旦我们完成了,我们就会回到运行时规则......所以在初始化时test5,is_constant_evaluated()是假的.(然后test6是一个不幸的语言特殊情况 - 您可以使用常量积分变量作为常量表达式,因此我们以相同的方式处理它们的初始化以用于这些目的.)
| 归档时间: |
|
| 查看次数: |
692 次 |
| 最近记录: |