C++中x+=x与x=x+y的区别及表达式重复调用f()结果相同的疑问
C++中x += y与x = x + y的区别及代码中f()两次调用的原因
一、x += y 与 x = x + y 的核心区别
- 左值求值次数不同:
x += y中,左操作数x只会被求值一次;而x = x + y里,x会被求值两次——一次作为右边操作数读取当前值,一次作为左边操作数接收赋值结果。如果x是带副作用的表达式(比如代码里的f(x, ...)),两种写法的执行差异会直接体现。 - 效率与语义差异(针对类类型):
若x是自定义类(如std::string),+=一般是类内重载的运算符,会直接修改原对象,避免临时对象的创建;而x = x + y会先通过+创建临时对象,再将临时对象的值赋给x,效率更低。另外,部分类可能只重载了+=未重载+,此时x = x + y会编译失败。
二、代码中第二个表达式调用两次f()的原因
结合你的代码和C++20标准规则分析:
第一个表达式:
f(x, "one") += 1
复合赋值运算符+=的执行逻辑是:先计算左操作数f(x, "one")(调用一次f(),x自增到6,返回x的引用),再计算右操作数1,接着对左操作数的引用执行+=1(x变为7),最后返回该引用作为表达式结果。全程仅调用一次f()。第二个表达式:
f(x, "two") = f(x, "three") + 1
普通赋值运算符=在C++17及之后的标准中规定:先计算右边整个表达式f(x, "three") + 1——这里会先调用f(x, "three")(x自增到6,返回x的引用),加1后得到7;接着计算左边表达式f(x, "two")——再次调用f()(x自增到7,返回x的引用);最后把右边的7赋值给左边的引用(此时x已是7,赋值后无变化)。
由于左右两边的f()表达式都需要被求值才能完成赋值,因此会调用两次f()。
你的代码输出也验证了这个逻辑:第二个表达式先输出<three>的日志,再输出<two>的日志,最终x和表达式结果均为7。
内容的提问来源于stack exchange,提问作者Hinata Chikao
相关产品推荐
相关产品推荐

