使用复合赋值的结果作为左值

时间:2013-05-13 10:50:05

标签: c++ c rvalue compound-assignment

我很惊讶这有效:

double x = 3;
double y = 2;

(x *= 2) += y;
std::cout << x << std::endl;

结果是8,这就是程序员想要实现的目标。但是我认为赋值运算符返回了一个右值 - 你怎么能分配给它的结果呢?

3 个答案:

答案 0 :(得分:2)

内置类型的赋值运算符返回左值 在C ++中(与C不同)。但你不能用它来修改 没有插入序列点的对象,所以你的例子是 未定义的行为(在C ++ 03-C ++ 11中发生了很大变化,并且 我似乎记得其中一个结果是你的代码 定义的)。

无论关于未定义行为的情况如何, 你最好写一下:

x = 2 * x + y;

它更具可读性。赋值运算符的事实 lvalues的结果实际上只有在结果时才可用 立即绑定到参考:

T&
SomeClass::f()
{
    //  ...
    return aTinSomeClass += 42;
}

即便如此,我还是用两个陈述写出来。

(C ++中的一般规则是,如果是运算符的结果 对应于内存中对象的值,那么它就是一个 左值。 C中没有一般规则。)

答案 1 :(得分:0)

在C ++中,复合赋值运算符返回左值,符合§5.17/ 1:

  

赋值运算符(=)和复合赋值运算符从右到左分组。所有都需要一个可修改的左值作为左操作数,并返回一个左值操作数的左值。

在这种情况下,使用*=会返回一个表示对象x的左值,然后将其用作+=运算符的左操作数。

也许您正在考虑像+*这样的简单算术运算符,它们会返回rvalues。

在C中,这些运算符不返回左值,因此无法进一步分配结果。

答案 2 :(得分:0)

在C ++中,赋值运算符的结果(包括复合赋值运算符(例如*=))是l值,因此是可赋值运算符。

在C中它们是r值,因此您的代码无效C代码。