何时使用逗号分隔C++中的两个或多个条件是否合适?

use*_*644 4 c++ conditional loops comma

我最近发现这是有效的C++语法:

int bar = 0;
for(int foo = 0; bar = 0, foo != 10; foo++)
{
    //some code
}
Run Code Online (Sandbox Code Playgroud)

我之前从未见过用作两个条件分隔符的逗号,所以我查看它是如何工作的.

我发现在用逗号分隔条件列表时,所有条件都会被执行,但只有最后一个被用作条件.例如:

while(function1(), function2(), function3())
{
    //code
} 
Run Code Online (Sandbox Code Playgroud)

这里,每次循环都会运行function1,function2和function3.但是,只有function3的返回值将用于确定是否保持循环.

我的问题是: 在任何情况下,这是最好的事情吗?

对我来说,这更有意义:

while(function3())
{
    function1();
    function2();

    //some code
} 
Run Code Online (Sandbox Code Playgroud)

何时使用逗号分隔条件是否恰当?

AnT*_*AnT 8

它取决于你的条件是什么意思:一个谓词,或者只是适用于周围环境预期条件的任何表达式.

从前一个角度来看,我会说使用逗号分隔条件是不合适的.根据自然定义,条件是一个特定于其布尔结果有价值的表达式,而不是其副作用(如果有的话).除了最后一个操作数之外,逗号运算符总是忽略其所有操作数的结果.这立即意味着除了逗号分隔序列中的最后一个位置之外,没有任何有意义的方法来指定条件.

逗号运算符的第一个和中间操作数应该是表达式,其目的在于它们的副作用.将这些表达称为条件是不合理的,因为它们的结果被忽略了.

从后一种观点来看,在期望条件的上下文中包含这样的副作用生成子表达式(如for循环标题的中间段)可能确实有意义,但在许多情况下它们会导致相当丑陋的代码.

我能提出的一个半可行的例子可能如下所示

for (ListItem* ptr = list_header; 
     assert(ptr != NULL), ptr->key != target_key;
     ptr = ptr->next);
Run Code Online (Sandbox Code Playgroud)

这应该强调列表绝对必须包含的事实target_key(即循环必须永远不会脱离列表的末尾).但我个人会以不同的方式表达出来.

你的例子中的变换while(function1(), function2(), function3())并不等同,因为一般情况下function3()可能取决于副作用function1(), function2().这意味着这些调用的顺序不能改变,这可能是他们所有人首先陷入这种while状态的主要原因.在这种情况下,表达它可能是有意义的while(function1(), function2(), function3()),但我宁愿将其转化为

do 
{
  function1();
  function2();
  if (!function3())
    break;
  ...
} while (true);
Run Code Online (Sandbox Code Playgroud)