Pie*_*rre 3 c++ language-lawyer value-categories
让我们想象一下这个函数:
C* get(C* c, int offset) {
return c + offset;
}
Run Code Online (Sandbox Code Playgroud)
我想知道对这个函数的调用是否被评估为一个纯右值:
C array_c[3];
C* c2 = get(array_c, 2);
Run Code Online (Sandbox Code Playgroud)
是get(array_c, 2)右值吗?
根据cppreference 上的值类别页面:
- 一个glvalue(“广义”左值)是对评估确定对象,位字段,或功能的同一性的表达;
- 一个prvalue(“纯”右值)是对评估是表达式:
- 计算与对象无关的值
- 创建一个临时对象并表示它
- 一个x值(一个“到期”值)是表示对象或位字段,其资源可以再利用的glvalue;
- 一个左值(所谓的,历史上,因为左值可以出现在赋值表达式的左手侧)是一种glvalue这不是一个x值;
在我们的示例中,表达式get(array_c, 2)指向一个已经存在的对象,该对象在调用后不会过期。所以我们可以说它是一个左值。此外,我们可以编写*get(array_c, 2) = C{};为表达式赋值。
但是,有两点让我认为它不是左值。首先,在cppreference的同一页面中:
以下表达式是纯右值表达式:
- 函数调用或重载运算符表达式,其返回类型为非引用
在我们的示例中,该get函数返回一个非引用,因此,根据这个定义,调用应该被评估为一个纯右值。
另外,我想知道是否get(array_c, 2)确实是一个临时值,使其成为纯右*get(array_c, 2)值并且是左值,因为我们可以为其分配一个值。
你怎么认为?函数调用是否被评估为左值、右值(或其他值)?
get(array_c, 2)和*get(array_c, 2)是两个不同的表达式,具有不同的值类别。
get按值本身返回指针,然后get(array_c, 2)被视为右值(纯右值)表达式。它就像你不能进行转让get(array_c, 2) = nullptr;或从中获得更多的地址&get(array_c, 2),它只是一样的,如果get返回其他类型一样int。
另一方面,*get(array_c, 2)是一个左值表达式。正如您所说,您可以对其进行赋值,无论有效与否,返回的指针是否有效都没有关系。
*p, 内置的间接表达式;
PS:可以对类类型的右值执行赋值;它不是确定左值表达式与否的绝对条件。