8

我刚刚通过阅读此页面开始学习 c++11 中的右值引用,但我被困在了第一页。这是我从该页面获取的代码。

  int& foo();
  foo() = 42; // ok, foo() is an lvalue
  int* p1 = &foo(); // ok, foo() is an lvalue

  int foobar();
  j = foobar(); // ok, foobar() is an rvalue
  int* p2 = &foobar(); // error, cannot take the address of an rvalue
  1. 为什么是foo()左值?是因为foo()返回int&基本上是左值吗?
  2. 为什么是foobar()右值?是因为foobar()退货int吗?
  3. 一般来说,你为什么要关心一个函数是否是一个右值?我想如果我阅读那篇文章的其余部分,我会得到我的答案。
4

1 回答 1

16

L-Values 是位置,R-Values 是可存储的值(即,可以分配的值:例如,命名空间是不可分配的;感谢@Maggyero 的编辑建议)。

所以:

  1. 因为foo()返回一个引用(int&),所以它本身就是一个左值。
  2. 正确的。foobar()是一个右值,因为foobar()返回int.
  3. 我们不太关心函数是否是 R 值。我们感到兴奋的是 R-Value 参考。

你指的那篇文章很有趣,我之前没有考虑过转发或在工厂中使用。我对 R-Value 引用感到兴奋的原因是移动语义,例如:

BigClass my_function (const int& val, const OtherClass & valb);

BigClass x;
x = my_function(5, other_class_instance);

在该示例中, x 被销毁,然后 my_function 的返回值通过复制构造函数复制到 x 中。为了从历史上解决这个问题,你会写:

void my_function (BigClass *ret, const int& val, const OtherClass & valb);

BigClass x;
my_function(&x, 5, other_class_instance);

这意味着现在my_function有副作用,而且它不是那么容易阅读。现在,使用 C++11,我们可以改为:

BigClass & my_function (const int& val, const OtherClass & valb);

BigClass x;
x = my_function(5, other_class_instance);

让它像第二个例子一样有效地运行。

于 2012-12-13T07:25:10.387 回答