[英]What type of value do overloaded operators return (for user-defined types): rvalue or lvalue?
我正在阅读Scott Meyers撰写的有效C ++:55种改善程序和设计的特定方法,他说:
让函数返回恒定值通常是不合适的,但是有时这样做可以减少客户端错误的发生,而又不放弃安全性或效率。 例如,考虑operator *函数的声明:
class Rational { ... };
const Rational operator*(const Rational& lhs, const Rational& rhs);
根据迈耶斯所说,这样做可以防止类似的“暴行”,如果a,b是原始类型,这将是非法的:
Rational a, b, c;
...
(a * b) = c;
这让我感到困惑,在尝试理解为什么上述赋值对于原始类型而不是用户定义类型是非法的时,我遇到了rvalues和lvalues
在查看了一些SO问题后,我仍然觉得我不太了解rvalues和lvalues是什么,但这是我的基本理解:lvalue引用内存中的位置,因此可以分配给它(可以在两侧of =运算符); 但是,不能将一个右值分配给它,因为它不引用内存位置(例如,函数返回值和文字中的临时值)
我的问题是:为什么赋予用户定义类型合法的两个数字/对象乘积合法(即使这没有意义)却不符合原语? 它与返回类型有关吗? 重载*运算符返回一个可赋值还是一个临时值?
[expr.call]/14:
如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用为左值,如果结果类型是对对象类型的右值引用,则函数调用为xvalue,否则为prvalue。
这是有道理的,因为结果没有“有名字”。 如果返回的引用,其含义是,这是一些地方的对象的引用, 它 “有名字”(这是一般但并非总是如此)。
然后是这个:
[expr.ass]/1:
赋值运算符(=)和复合赋值运算符均从右到左分组。 它们都需要可修改的左值作为其左操作数; 它们的结果是一个指向左操作数的左值。
这就是说,赋值要求左侧有一个左值。 到现在为止还挺好; 您已经自己解决了。
那么,非const
函数调用结果如何工作?
按照特殊规则!
[over.oper]/8:
[..]一些预定义的运算符(例如+ =)在应用于基本类型时要求操作数为左值; 操作员功能不需要此功能。
...和=
施加到类类型的对象调用的操作者的功能 。
我不能轻易回答“为什么”:从表面上看,在处理类时放宽此限制是有意义的,并且对内置函数的原始(继承)限制似乎总是有点过分(我认为)但出于兼容性原因,必须保留。
但是随后,像Meyers这样的人指出,现在返回const
值以有效地“撤消”此更改变得很有用 。
最终,我不会为找到一种合理的理由而努力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.