函数调用返回指向对象的指针是纯右值吗?
Is a function call returning a pointer to an object a prvalue?
让我们想象一下这个函数:
C* get(C* c, int offset) {
return c + offset;
}
我想知道对该函数的调用是否被评估为纯右值:
C array_c[3];
C* c2 = get(array_c, 2);
get(array_c, 2)
是纯右值吗?
根据 cppreference 上的 Value categories 页面:
- a glvalue (“generalized” lvalue) is an expression whose evaluation determines the identity of an object, bit-field, or function;
- a prvalue (“pure” rvalue) is an expression whose evaluation either :
- computes a value that is not associated with an object
- creates a temporary object and denotes it
- an xvalue (an “eXpiring” value) is a glvalue that denotes an object or bit-field whose resources can be reused;
- an lvalue (so-called, historically, because lvalues could appear on the left-hand side of an assignment expression) is a glvalue that is not an xvalue;
在我们的示例中,表达式 get(array_c, 2)
指向调用后不会过期的已经存在的对象。所以我们可以说它是一个左值。此外,我们可以写*get(array_c, 2) = C{};
来给表达式赋值。
但是,有两点让我觉得它不是左值。首先在cppreference的同一页中:
The following expressions are prvalue expressions:
- a function call or an overloaded operator expression, whose return type is non-reference
在我们的示例中,get
函数 returns 是一个非引用,因此,根据此定义,调用应评估为纯右值。
此外,我想知道 get(array_c, 2)
是否确实是一个使它成为纯右值的临时值,而 *get(array_c, 2)
是一个左值,因为我们可以为其赋值。
你怎么看?函数调用是否被评估为左值、纯右值(或其他)?
get(array_c, 2)
和 *get(array_c, 2)
不是同一个表达式;它们不必都属于同一值类别。
get(array_c, 2)
是纯右值。
The following expressions are prvalue expressions:
...
- a function call or an overloaded operator expression, whose return type is non-reference...
*get(array_c, 2)
是左值。
The following expressions are lvalue expressions:
...
*p
, the built-in indirection expression;
(Source)
get(array_c, 2)
和 *get(array_c, 2)
是两个不同的表达式,具有不同的值类别。
get
returns指针本身的值,则get(array_c, 2)
被认为是右值(prvalue)表达式。您不能像 get(array_c, 2) = nullptr;
那样对其进行赋值,也不能像 &get(array_c, 2)
那样从中获取地址,这与 get
returns 其他类型 int
一样。
另一方面,*get(array_c, 2)
是一个 lvalue expression。正如你所说,你可以对其进行赋值,有效与否,返回的指针有效与否无关紧要。
*p
, the built-in indirection expression;
PS:可以对class类型的右值进行赋值;它不是确定左值表达式与否的绝对条件。
让我们想象一下这个函数:
C* get(C* c, int offset) {
return c + offset;
}
我想知道对该函数的调用是否被评估为纯右值:
C array_c[3];
C* c2 = get(array_c, 2);
get(array_c, 2)
是纯右值吗?
根据 cppreference 上的 Value categories 页面:
- a glvalue (“generalized” lvalue) is an expression whose evaluation determines the identity of an object, bit-field, or function;
- a prvalue (“pure” rvalue) is an expression whose evaluation either :
- computes a value that is not associated with an object
- creates a temporary object and denotes it
- an xvalue (an “eXpiring” value) is a glvalue that denotes an object or bit-field whose resources can be reused;
- an lvalue (so-called, historically, because lvalues could appear on the left-hand side of an assignment expression) is a glvalue that is not an xvalue;
在我们的示例中,表达式 get(array_c, 2)
指向调用后不会过期的已经存在的对象。所以我们可以说它是一个左值。此外,我们可以写*get(array_c, 2) = C{};
来给表达式赋值。
但是,有两点让我觉得它不是左值。首先在cppreference的同一页中:
The following expressions are prvalue expressions:
- a function call or an overloaded operator expression, whose return type is non-reference
在我们的示例中,get
函数 returns 是一个非引用,因此,根据此定义,调用应评估为纯右值。
此外,我想知道 get(array_c, 2)
是否确实是一个使它成为纯右值的临时值,而 *get(array_c, 2)
是一个左值,因为我们可以为其赋值。
你怎么看?函数调用是否被评估为左值、纯右值(或其他)?
get(array_c, 2)
和 *get(array_c, 2)
不是同一个表达式;它们不必都属于同一值类别。
get(array_c, 2)
是纯右值。
The following expressions are prvalue expressions:
...
- a function call or an overloaded operator expression, whose return type is non-reference...
*get(array_c, 2)
是左值。
The following expressions are lvalue expressions:
...
*p
, the built-in indirection expression;
(Source)
get(array_c, 2)
和 *get(array_c, 2)
是两个不同的表达式,具有不同的值类别。
get
returns指针本身的值,则get(array_c, 2)
被认为是右值(prvalue)表达式。您不能像 get(array_c, 2) = nullptr;
那样对其进行赋值,也不能像 &get(array_c, 2)
那样从中获取地址,这与 get
returns 其他类型 int
一样。
另一方面,*get(array_c, 2)
是一个 lvalue expression。正如你所说,你可以对其进行赋值,有效与否,返回的指针有效与否无关紧要。
*p
, the built-in indirection expression;
PS:可以对class类型的右值进行赋值;它不是确定左值表达式与否的绝对条件。