这些术语似乎有不同的定义 ,但我总是想到一个意味着另一个; 我不能想到任何情况下,一个expression是透明的,但不是纯粹的,反之亦然。 维基百科针对这些概念维护不同的文章,并说: 从参考透明度 : 如果expression式中涉及的所有函数都是纯函数,那么expression式就是透明的。 另外,如果expression式中包含一些不纯的函数,那么它们的值将被丢弃,并且其副作用不明显。 从纯粹的表情 : 纯函数是构造纯expression式所必需的。 纯粹的expression通常被认为是透明的。 我觉得这些陈述混淆。 如果来自所谓的“不纯function”的副作用不足以允许不执行它们(即,用它的值replace对这样的function的调用),而不实质上改变程序,则它就像在第一个地方,不是吗? 有没有更简单的方法来理解纯粹的expression和透明的expression之间的区别? 如果有差异,清楚地表明它的示例expression将不胜感激。
有时, if语句可能相当复杂或冗长,所以为了可读性,最好在if之前提取复杂的调用。 例如: if (SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall()) { // do stuff } 进入这个 bool b1 = SomeComplicatedFunctionCall(); bool b2 = OtherComplicatedFunctionCall(); if (b1 || b2) { //do stuff } (提供的例子不是那么糟糕,只是为了说明…想象其他多个参数的调用等) 但是通过这个提取,我失去了短路评估(SCE)。 我真的每次都失去SCE吗? 是否有一些情况下编译器被允许“优化”,仍然提供SCE? 有没有方法保持第二个片段的可读性不会丢失SCE?
对不起再次打开这个话题,但想到这个话题本身已经开始给我一个未定义的行为。 想要进入明确的行为区域。 特定 int i = 0; int v[10]; i = ++i; //Expr1 i = i++; //Expr2 ++ ++i; //Expr3 i = v[i++]; //Expr4 我想到了上面的expression式(按此顺序) operator=(i, operator++(i)) ; //Expr1 equivalent operator=(i, operator++(i, 0)) ; //Expr2 equivalent operator++(operator++(i)) ; //Expr3 equivalent operator=(i, operator[](operator++(i, 0)); //Expr4 equivalent 现在来到这里的行为是从C ++ 0x重要的引号。 “对expression式(或子expression式)的评估通常包括值计算(包括确定左值评估对象的身份和获取先前赋值给对象进行右值评估的值)以及副作用的启动“。 $ 1.9 / 15-“如果对标量对象的副作用不是相对于同一个标量对象的另一个副作用或使用相同标量对象的值进行值计算,那么行为是未定义的。 [注:与不同参数expression式相关的值计算和副作用是不确定的。 – […]