and - 方法链中的C++执行顺序



chaining order-of-evaluation (3)

该程序的输出:

#include <iostream> 
class c1
{   
  public:
    c1& meth1(int* ar) {
      std::cout << "method 1" << std::endl;
      *ar = 1;
      return *this;
    }
    void meth2(int ar)
    {
      std::cout << "method 2:"<< ar << std::endl;
    }
};

int main()
{
  c1 c;
  int nu = 0;
  c.meth1(&nu).meth2(nu);
}

方法是:

method 1
method 2:0

meth2() 启动时,为什么 nu 不为1?


Answer #1

因为评估订单未指定。

你甚至在调用 meth1 之前看到 main 中的 nu 被评估为 0 。 这是链接的问题。 我建议不要这样做。

只需制作一个简单,清晰,易读,易于理解的程序:

int main()
{
  c1 c;
  int nu = 0;
  c.meth1(&nu);
  c.meth2(nu);
}

Answer #2

在1998 C ++标准中,第5节,第4段

除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的评估顺序以及副作用发生的顺序是未指定的。 在前一个和下一个序列点之间,标量对象应通过表达式的计算最多修改其存储值一次。 此外,只能访问先前值以确定要存储的值。 对于完整表达式的子表达式的每个允许排序,应满足本段的要求; 否则行为未定义。

(我省略了对脚注#53的引用,这与此问题无关)。

基本上,必须在调用 c1::meth1() 之前评估 &nu ,并且必须在调用 c1::meth2() 之前计算 nu 。 但是,没有要求在 nu 之前评估 &nu (例如,允许首先计算 nu ,然后是 &nu ,然后调用 c1::meth1() - 这可能是你的编译器正在做的事情)。 因此,在计算 main() nu 之前,不能保证在 c1::meth1() 表达式 *ar = 1 ,以便传递给 c1::meth2()

后来的C ++标准(我目前在PC上没有使用的标准)具有基本相同的条款。


Answer #3

我认为在编译时,在实际调用函数meth1和meth2之前,参数已经传递给它们。 我的意思是当你使用“c.meth1(&nu).meth2(nu);” 值nu = 0已经传递给meth2,所以后者改变“nu”无关紧要。

你可以试试这个:

#include <iostream> 
class c1
{
public:
    c1& meth1(int* ar) {
        std::cout << "method 1" << std::endl;
        *ar = 1;
        return *this;
    }
    void meth2(int* ar)
    {
        std::cout << "method 2:" << *ar << std::endl;
    }
};

int main()
{
    c1 c;
    int nu = 0;
    c.meth1(&nu).meth2(&nu);
    getchar();
}

它会得到你想要的答案





operator-precedence