c++ - 返回值的范围和赋值

标签 c++ c++11

 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/

相关文章:

c++ - 与当前 OpenGL 上下文对应的唯一 OpenCL 上下文

c++ - 使用adjacent_difference编译错误

c++ - Qt - QStackedWidget 用法

C++ 对字符串中的字符进行反向排序

c++ - 如何使用 boost-range 在函数中封装自定义迭代器

c++ - 带有 std::shared_ptr 的视觉泄漏检测器

c++ - 是否可以在运行时选择可以访问类私有(private)成员的函数?

c++ - 如何让这段涉及 unique_ptr 的代码进行编译?

c++ - std::bind 和 std::weak_ptr

c++ - 如何将 std::promise 传递到线程中?通过 std::move 还是通过 std::shared_ptr?