为什么左操作数所需的错误左值不会出现在字符串中?

why error lvalue required as left operand does not exhibit for strings?

在下面的代码片段中,为什么第 2 + 3 = 5 行语句出错但下一个分配给字符串连接的语句编译成功?

#include <string>

int main() {                                                                                                                                                  
   2 + 3 = 5;   //  Error: lvalue required as left operand of assignment                                                                                                                                             
   std::string("2") + std::string("3") = std::string("5");  // Compiles successfully. why?                                                                                                 
   return 0;                                                                                                                                                 
}

我的理解是表达式 std::string("2") + std::string("3") = std::string("5") 的左侧会产生临时值 rvalue。这意味着我要分配给 rvalue - 就像 2 + 3 = 5 一样。所以它也应该给出 lvalue required as left operand of assignment 错误。但事实并非如此。

说明

对于class类型,赋值是通过复制和移动赋值运算符实现的。 std::string 是一个 class,所以

std::string("2") + std::string("3") = std::string("5")

只是

的语法糖
(std::string("2") + std::string("3")).operator=(std::string("5"))

operator= 是一个成员函数。通常,可以在左值和右值上调用成员函数。因此,这个表达式是有效的。

标准参考

对于非重载 operator=(即对于 int):[expr.ass]/1

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. [...]

对于重载operator=(对于std::string):[expr.ass]/4

If the left operand is of class type, the class shall be complete. Assignment to objects of a class is defined by the copy/move assignment operator ([class.copy], [over.ass]).

(所有人都强调我的)

该规则仅适用于内置类型的对象,例如 int

不适用于类。

该规则可能被认为对 类 的限制过于严格,其运算符可以重载以执行各种操作……或者可能在 C++ 出现时被认为过于严格,但它不会是好吧,也可以通过放宽内置函数的规则来破坏旧的 C 代码。

无论如何,加法的结果实际上是一个左值,因为当您 return 来自函数的 std::string& 之类的左值引用时,这就是您得到的结果。尽管事实上加法的两个操作数都是右值表达式和临时对象。这可能有点令人惊讶,there's a proposal to do better at "propagating value category" 在这种情况下,既然语言为我们提供了这样做的工具。