c++ - 重载运算符返回什么类型的值(对于用户定义类型): rvalue or lvalue?

标签 c++ rvalue lvalue

我正在阅读 Scott Meyers 写的《Effective C++: 55 Specific Ways to Improve Your Programs and Design》,他说:

Having a function return a constant value is generally inappropriate, but sometimes doing so can reduce the incidence of client errors without giving up safety or efficiency. For example, consider the declaration of the operator* function:

class Rational { ... };

const Rational operator*(const Rational& lhs, const Rational& rhs);

根据 Meyers 的说法,这样做可以防止像这样的“暴行”,如果 a、b 是原始类型,这将是非法的:

Rational a, b, c;

...

(a * b) = c;

这让我很困惑,在试图理解为什么上述赋值对于基本类型而不是用户定义类型是非法的时,我遇到了右值和左值

在浏览了一些SO问题后,我仍然觉得我对右值和左值没有很强的把握,但这是我的基本理解:左值引用内存中的一个位置,因此可以被分配给(它可以是= 运算符的两侧也是如此);但是,无法分配右值,因为它不引用内存位置(例如函数返回和文字中的临时值)

我的问题是:为什么分配给两个数字/对象的乘积对于用户定义类型是合法的(即使它没有意义)而不是基元?它与返回类型有关吗?重载的 * 运算符返回可分配值还是临时值?

最佳答案

[expr.call]/14: A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.

这是有道理的,因为结果没有“有名字”。如果您返回一个引用,则意味着它是对某个“有名称”(通常但并非总是如此)的某个对象的引用。

然后是这样的:

[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; their result is an lvalue referring to the left operand.

这表示赋值操作需要左侧有一个左值。到目前为止,一切都很好;您自己已经介绍过这一点。

const函数调用结果如何起作用?

根据特殊规则!

[over.oper]/8:: [..] Some predefined operators, such as +=, require an operand to be an lvalue when applied to basic types; this is not required by operator functions.

... 和 = 应用于类类型的对象会调用运算符函数

我无法轻易回答“为什么”:从表面上看,在处理类时放宽此限制是有意义的,并且对内置函数的原始(继承)限制总是显得有点过分(在我的意见),但出于兼容性原因必须保留。

但是像 Meyers 这样的人指出,现在返回 const 值以有效“撤消”此更改变得有用(某种程度上)。

最终我不会太努力地寻找强有力的理由。

关于c++ - 重载运算符返回什么类型的值(对于用户定义类型): rvalue or lvalue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57590241/

相关文章:

c# - C# WinMobile 6.1 项目中的 C++ DLL - 1c2 机器 (Thumb) 与 14c 机器 (x86)

c++ - 如何将 std::function 分配给 C++ 中的运算符?

C++构造函数问题

c - "&(epage->incoming[0]) = spage;"和 "&(epage->incoming[p2]) = spage;"之间的区别

c++ - 为什么占用临时地址是非法的?

c++ - 实际函数调用计数与 EXPECT_CALL(*mock, display()) 不匹配

c++ - 为什么 Utf-8 在 Qt 5 中无法工作?

c++ - C++ 中的引用和字面量

c++ - 为什么在特殊成员函数中将 r 值绑定(bind)到 const 左值引用是非法的?

c++ - 临时绑定(bind)到左值引用