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 }
不允许为内置类型的返回值赋值,但是允许赋值给用户定义类型的返回值是什么?如何管理内存而不是另一个?
答案 0 :(得分:1)
查看有关值类别的this article。
值类别
每个C ++表达式(具有操作数,文字,变量名等的运算符)由两个独立属性表征:类型和值类别。 [...]
<强> prvalue 强>
以下表达式是prvalue表达式:
[...]
- 函数调用或非引用返回类型的重载运算符表达式,例如str.substr(1,2)
好的,我们知道表达式func1()
和func2()
是prvalues。
[...]
<强>右值强>
右值表达式是prvalue或xvalue。
现在我们知道prvalues是rvalues。
属性:
[...]
rvalue不能用作内置赋值或复合赋值运算符的左操作数。
[...]
这是重要的部分。请注意,该规则仅排除内置分配。仍然允许类类型的复制赋值运算符。
因此,内置运算符和类类型运算符之间的区别在于它们被语言规则区别对待。
现在,您可能想知道,为什么分配不允许内置类型?嗯,没有用例。赋值没有副作用(除了改变左手操作数的值),并且丢弃返回值。如果你写它,你很可能犯了一个错误。不允许它对程序员有帮助。
现在,您可能想知道,是不是分配给rvalue类类型也没用?好吧,它可能不是!类类型可以具有具有副作用的用户定义的赋值运算符。并且类类型可以具有具有副作用的析构函数,具体取决于先前执行的赋值。我无法保证这是Bjarne或委员会在指定语言时使用的理由,但这些是我对此事的看法。