1 class Foo{
2
3 };
4
5 Foo func1(){
6 Foo f;
7 return f;
8 }
9
10 int func2(){
11 int a = 2;
12 return a;
13 }
14
15 int main(int argc, char** argv){
16 Foo var1;
17 func1() = var1; //OK
18 func2() = 1; //error: expression is not assignable
19 return 0;
20 }
不允许对内置类型的返回值赋值,而允许对自定义类型的返回值赋值的根本原因是什么?如何管理允许一个而不允许另一个的内存?
最佳答案
看看this article关于值(value)类别。
Value categories
Each C++ expression (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a type and a value category. [...]
prvalue
The following expressions are prvalue expressions:
[...]
- function call or an overloaded operator expression of non-reference return type, such as str.substr(1, 2)
好的,所以我们知道表达式 func1()
和 func2()
是纯右值。
[...]
rvalue
An rvalue expression is either prvalue or xvalue.
现在我们知道纯右值是右值。
Properties:
[...]
An rvalue can't be used as the left-hand operand of the built-in assignment or compound assignment operators.
[...]
这是重要的部分。请注意,该规则仅排除内置赋值。仍然允许类类型的复制赋值运算符。
因此,内置运算符和类类型运算符之间的区别在于,它们在语言规则中的处理方式不同。
现在,您可能想知道,为什么不允许对内置类型进行赋值?好吧,它没有用例。赋值没有副作用(除了改变左手操作数的值)并且返回值被丢弃。如果你写了它,你很可能犯了一个错误。不允许它对程序员有帮助。
现在,您可能想知道,分配给右值类类型不是也没有用吗?好吧,它可能不是!类类型可以具有用户定义的具有副作用的赋值运算符。并且类类型可以具有析构函数,这些析构函数会根据先前执行的赋值产生副作用。我不能保证这就是 Bjarne 或委员会在指定语言时使用的推理,但这是我对此事的看法。
关于c++ - 返回值的范围和赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40336641/