为什么在本例中int foo()是一个右值,而int&foo()是一个左值?

时间:2019-08-26 08:41:31

标签: c++ rvalue-reference lvalue

我们有以下代码示例:

// lvalues:
  //
  int i = 42;
  i = 43; // ok, i is an lvalue
  int* p = &i; // ok, i is an lvalue
  int& foo();
  foo() = 42; // ok, foo() is an lvalue
  int* p1 = &foo(); // ok, foo() is an lvalue

// rvalues:
  //
  int foobar();
  int j = 0;
  j = foobar(); // ok, foobar() is an rvalue
  int* p2 = &foobar(); // error, cannot take the address of an rvalue
  j = 42; // ok, 42 is an rvalue

我试图理解为什么这样一个普通的函数定义:

int foobar();

应该是一个右值,而该函数具有相同的功能,但具有对象引用作为返回类型,如下所示:

int& foobar();

是一个左值。 (第二部分以某种方式自然而然地出现了,因为我们在定义函数时明确要求并因此保留了引用。但是,第一个示例对我来说很难理解,因为我期望函数以某种方式隐式地扣除了存储位置基于一个可能是错误的假设,即每个函数在内存中都有其自己的不可更改的位置,因此,总之,第一个示例也应该是左值引用。请首先尝试说明这一方面。

我了解:

  

左值是一个引用存储位置的表达式,它允许我们通过&运算符获取该存储位置的地址。一个右值是一个不是左值的表达式。

但是,如上所述,我最感兴趣的是关于左值/右值概念如何对待与简单对象相对或相关的功能。

谢谢!

1 个答案:

答案 0 :(得分:4)

foobar()不是函数。这是一个函数调用。对它的求值是调用函数的结果,即一个int,它是一个右值。

以下是将函数分配给引用的方法(比获取其地址更好的测试):

int (&a)() = foo; // OK
int (&&b)() = foo; // OK

这是分配功能地址的方式

int (*a)() = &foo; // OK
  

我了解:“左值是一个引用内存位置的表达式,它允许我们通过&运算符获取该内存位置的地址。右值是不是左值的表达式。”

嗯...这是一个非常简单的定义。如果您对此主题感兴趣,请点击以下链接:

What are rvalues, lvalues, xvalues, glvalues, and prvalues?

Value categories