“IF”参数评估顺序?

新手上路,请多包涵
if(a && b)
{
  do something;
}

是否有可能从右到左评估参数(b -> a)?

如果“是”,什么会影响评估顺序?

(我正在使用 VS2008)

原文由 winnerrrr 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 808
2 个回答

评估顺序由标准指定,为 left-to-right 。最左边的表达式总是首先使用 && 子句进行评估。

如果您想首先评估 b

 if(b && a)
{
  //do something
}

如果两个参数都是方法,并且您希望无论结果如何都对它们进行评估:

 bool rb = b();
bool ra = a();

if ( ra && rb )
{
  //do something
}

原文由 Luchian Grigore 发布,翻译遵循 CC BY-SA 3.0 许可协议

在 C++ 中,只有少数几个运算符可以保证求值顺序

  • operator && 首先评估左操作数,如果该值在逻辑上是 false 然后它避免评估右操作数。例如 if (x > 0 && k/x < limit) ... 典型用途是避免除零问题。

  • operator || 首先评估左操作数,如果该值在逻辑上是 true 然后它避免评估右操作数。例如 if (overwrite_files || confirm("File existing, overwrite?")) ... 在设置标志 overwrite_files 时不会询问确认。

  • operator , 先计算左操作数,然后再计算右操作数,返回右操作数的值。该运算符不经常使用。请注意,函数调用中参数之间的逗号 不是 逗号运算符,并且无法保证评估顺序。

  • The ternary operator x?y:z evaluates x first, and then depending on the logical value of the result evaluates either only y or only z .

对于所有其他运算符,未指定评估顺序。

情况实际上更糟,因为不是没有指定顺序,而是表达式根本没有“顺序”,例如在

std::cout << f() << g() << x(k(), h());

可能会按顺序调用函数 h-g-k-x-f (这有点令人不安,因为 << 运算符的心理模型以某种方式传达了顺序性的概念,但实际上仅在顺序结果放在流中,而不是按照计算结果的顺序)。

显然表达式中的值依赖可能会引入一些顺序保证; for example in the above expression it’s guaranteed that both k() and h() will be called before x(...) because the return values from both are needed to call x (C++ 并不 懒惰)。

另请注意,对 &&||, 的保证仅对预定义的运算符有效。如果您为您的类型重载这些运算符,它们在这种情况下将像正常的函数调用一样,并且操作数的评估顺序将是未指定的。

自 C++17 以来的变化

C++17 引入了一些关于评估顺序的额外特定保证(例如在左移运算符中 << )。有关所有详细信息,请参阅 https://stackoverflow.com/a/38501596/320726

原文由 6502 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题