我很惊讶这有效:
double x = 3;
double y = 2;
(x *= 2) += y;
std::cout << x << std::endl;
结果是 8,这就是程序员试图达到的结果。但我认为赋值运算符返回了一个右值——你怎么能把它赋值给一个的结果?
我很惊讶这有效:
double x = 3;
double y = 2;
(x *= 2) += y;
std::cout << x << std::endl;
结果是 8,这就是程序员试图达到的结果。但我认为赋值运算符返回了一个右值——你怎么能把它赋值给一个的结果?
内置类型的赋值运算符在 C++ 中返回一个左值(与 C 中不同)。但是你不能在没有中间序列点的情况下使用它来修改对象,所以你的例子是未定义的行为(在 C++03-C++11 中改变了很多,我似乎记得其中一个结果使你的代码定义)。
无论关于未定义行为的情况如何,您最好写:
x = 2 * x + y;
它更具可读性。赋值运算符产生左值的事实仅在结果立即绑定到引用时才可用:
T&
SomeClass::f()
{
// ...
return aTinSomeClass += 42;
}
即使那样,我也会用两个语句来写。
(C++ 中的一般规则是,如果运算符的结果对应于内存中对象的值,则它是左值。C 中没有一般规则。)
在 C++ 中,复合赋值运算符返回左值,根据 §5.17/1:
赋值运算符 (
=
) 和复合赋值运算符都从右到左分组。所有这些都需要一个可修改的左值作为它们的左操作数,并返回一个指向左操作数的左值。
在这种情况下,使用*=
返回一个左值,表示该对象x
,然后用作运算符的左操作数+=
。
也许您正在考虑简单的算术运算符+
,例如*
返回右值。
在 C 中,这些运算符不返回左值,因此无法进一步分配结果。
在 C++ 中,赋值运算符的结果,包括复合赋值运算符(例如*=
)是左值,因此是可赋值的。
在 C 中它们是 r 值,因此您的代码无效 C 代码。