【问题标题】:Comma operator used in assignment赋值中使用的逗号运算符
【发布时间】:2016-05-08 17:12:50
【问题描述】:

考虑代码:

int i, j;
i = (i = 1, j = 3);
i++;
cout<<i<<" "<<j;

这打印了4 3 (c++14)。

我读到逗号运算符计算其左侧的表达式并返回其右侧的表达式。现在如果这是正确的,我想知道 j = 3 的返回值是多少?是右值吗?还是对左值的引用?

这实际上是如何工作的?

【问题讨论】:

  • 我很抱歉多出了 3 行,但在这种情况下可能不应该适用的最小字数限制,因为我相信我的问题是相当清楚的。

标签: c++ comma-operator


【解决方案1】:

我想知道j = 3的返回值是多少?

赋值操作*返回(或“评估”)对操作左侧的引用,在本例中为 j

所以i = (i = 1, j = 3); 等同于:

i = 1;
j = 3;
i = j;

*对于内置类型。自定义 operator= 重载可能会返回任何他们想要的,但建议返回对 *this 的引用,因为这是 C++ 程序员的预期行为。

【讨论】:

  • 所以如果我将 i 增加 1 那么这意味着 j 也应该增加,因为你说它返回一个 reference!所以第 3 行应该是 i = &j;?
  • @SaurabhRaje 它返回一个引用,但引用的值被复制i(因为i不是一个引用变量)。另外,不要混淆&amp;variabletype&amp;,前者是地址操作符,后者声明一个引用类型。
  • 是的,我知道其中的区别,但我认为编译器可能会隐式地将其类型转换为引用,因为我给了我一个内存地址......这只是一个猜测,我可以大错特错
  • 是的,你错了。编译器从不隐式取消引用指针。
【解决方案2】:

为了计算 (i=1, j=3),它从左到右计算以逗号分隔的表达式,并返回最后一个(最右边)表达式的值。所以它计算 i=1(i 变为 1),然后计算 j=3(j 变为 3),然后返回 3。

计算 (i=1, j=3) 后返回 3,它执行赋值,将 i 设置为 3。

然后计算 i++,将 i 设置为 4。

然后打印 i 和 j。

【讨论】:

    【解决方案3】:

    赋值运算符返回一个引用左操作数的左值。它从右到左分组。 ([expr.ass])。请注意,说返回对左值的引用是没有意义的——它要么返回一个左值,要么不返回。

    逗号运算符从左操作数执行值计算和副作用,丢弃它们,然后对右操作数执行相同的操作。 ([expr.comma])

    因此重构逗号运算符将产生以下等效代码:

    i = 1;      // left operand, value discarded
    i = j = 3;  // right operand, value preserved
    i++;
    

    然后重构复合赋值将产生以下仍然等效的代码:

    i = 1;
    j = 3;     // rightmost assignment
    i = j;     // leftmost assignment
    i++;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 2022-08-17
      • 2010-12-15
      • 2012-07-15
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多