1

我经常遇到这样的情况:

if (A && B)
{
    C();
}
else
{
    D();
}

但是当A是时constexpr,没有办法向 if 语句表明 if Bis not also constexpr。此外,启用使用的解决方法constexpr是丑陋的:

if constexpr (A)
{
    if (B)
    {
        C();
    }
    else
    {
        D();
    }
}
else
{
    D();
}

是否有使constexpr if陈述更灵活的建议,即。考虑哪些条件是constexpr?如果没有,除了假设编译器会做正确的事情(他们并不总是这样做)之外,是否有解决这种情况的方法。

4

2 回答 2

3

if constexpr不是“更快if”。if当条件表达式恰好是常量表达式时,这不是您使用的语句。当您希望编译器在编译时测试条件时,甚至不是if您使用的语句(编译器能够自行执行此操作)。

if constexpr第二个示例中用法的含义是,除非由 表示的条件为真,否则表达式C()并不意味着是有效的 C++ 。A这就是为什么if constexpr你用;保护代码块的原因。这就是为什么一开始就将该功能添加到语言中的原因。显然你可以将它用于其他事情,但如果你关心的只是让编译器在编译时评估条件表达式,那么你不应该使用if constexpr.

正是出于这个原因,你所要求的东西没有到来。

查看您的第二个示例,在if constexpr仅部分是常量表达式的表达式中复制 ' 行为的困难变得显而易见。规则需要相当复杂。在您的示例中,D()即使A为真,也必须是有效的 C++ 代码,因为B在运行时可能为假。

您需要构建一些相当复杂的规则,以了解此类“部分 constexpr”表达式如何禁止评估各种代码分支。这很容易导致用户难以理解复杂表达式何时会剔除哪些分支,何时不会。

在这些情况下,最好让用户把它写成长格式。

于 2020-09-09T01:28:12.790 回答
0

除了假设编译器会做正确的事情(他们并不总是这样做)之外,是否有解决这种情况的方法。

好吧...当您的示例中的代码是函数的所有内容void(或函数的最后一部分void)时...下面的内容呢?

if constexpr ( A )
   if ( B )
    {
      C();

      return;
    }

D();

否则(如果您的代码是更大函数的非最终片段),我想您可以将其包装在while

while ( 1 )
 {
   if constexpr ( A )
      if ( B )
       {
         C();

         break;
       }

   D();

   break;
 }

但我想这是一个“假设编译器会做正确的事情”的情况。

于 2020-09-09T00:50:43.550 回答