为啥 int foo() 是一个右值,而 int& foo() 在这个例子中是一个左值?
Posted
技术标签:
【中文标题】为啥 int foo() 是一个右值,而 int& foo() 在这个例子中是一个左值?【英文标题】:Why is int foo() an rvalue, while int& foo() is an lvalue in this example?为什么 int foo() 是一个右值,而 int& foo() 在这个例子中是一个左值? 【发布时间】:2019-08-26 08:41:31 【问题描述】:我们有以下代码示例:
// 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();
是一个左值。 (第二部分很自然,因为我们在定义函数时特别要求并因此保留引用。但是,第一个示例对我来说很难掌握,因为我期望函数的内存位置以某种方式隐式扣除,基于这样的假设——这可能是错误的——每个函数在内存中都有自己的、不可更改的位置,总之,第一个示例也应该是一个左值引用)。请先试着解释一下这方面。
我明白了:
左值是一个引用内存位置的表达式,它允许我们通过 & 运算符获取该内存位置的地址。右值是不是左值的表达式。
但是,如上所述,我最感兴趣的是如何根据左值/右值概念处理函数,而不是简单对象或与之相关的函数。
谢谢!
【问题讨论】:
你误解了错误:不是函数是右值,而是它返回的东西。 @freakish 能否请您扩展一下这个主题? 见博洛夫的回答。 【参考方案1】:foobar()
不是函数。这是一个函数调用。它的评估是调用函数的结果,即int
,它是一个右值。
下面是你如何将函数分配给一个引用(这是一个比获取它的地址更好的测试):
int (&a)() = foo; // OK
int (&&b)() = foo; // OK
这是分配函数地址的方式
int (*a)() = &foo; // OK
我理解:“左值是一个引用内存位置的表达式,它允许我们通过 & 运算符获取该内存位置的地址。右值是一个不是左值的表达式。”
嗯...这是一个非常简单的定义。如果您对该主题感兴趣,这里有一些链接:
What are rvalues, lvalues, xvalues, glvalues, and prvalues?
Value categories
【讨论】:
以上是关于为啥 int foo() 是一个右值,而 int& foo() 在这个例子中是一个左值?的主要内容,如果未能解决你的问题,请参考以下文章