问题描述
我想澄清一下 C++ 值类别。
struct Foo {...};
void do_something(Foo{});
Foo{} 高于 r 值还是 x 值?
我知道存在值类别的层次结构,并且 r 值实际上是 x 值或 pr 值。我也知道标准说“临时物化是一个 x 值”,但我不确定临时物化的创建是否符合这个定义。
但我不确定的是 gl-value 和 r-value 是否是层次结构中的“抽象”类别,叶子(l 值、x 值和 pr 值)是实际实现.
有人可以为我解释一下吗?
解决方法
来自 https://eel.is/c++draft/basic.lval(2021 年 4 月 2 日访问):
每个表达式都完全属于一个基本的 此分类法中的分类:lvalue、xvalue 或 prvalue。这 表达式的属性称为其值类别。
这回答了您的问题,即 gl-value 和 r-value 是否是值的类别:它们是。
关于您的特定情况是什么类型的值,让我们看看 xvalue:
- xvalue 是一个左值,它表示一个对象的资源可以被重用(通常是因为它的生命周期即将结束)。
[ ... 剪 ... ]
# [注 3:一个表达式是 xvalue,如果它是:
- (4.1) 调用函数的结果,无论是隐式还是显式,其返回值 type 是对对象类型 ([expr.call]) 的右值引用,
- (4.2) 对对象类型 ([expr.type.conv],[expr.dynamic.cast],[expr.static.cast] [expr.reinterpret.cast],[expr.const.cast],[expr.cast]),
- (4.3) 下标操作 一个 xvalue 数组操作数 ([expr.sub]),
- (4.4) 类成员访问 指定非引用类型的非静态数据成员的表达式 其中对象表达式是 xvalue ([expr.ref]),或
- (4.5) a .* 指向成员的指针表达式,其中第一个操作数是一个 xvalue 和第二个操作数是指向数据成员的指针 ([expr.mptr.oper])。
您的情况似乎不适合其中任何一个。现在让我们看看纯右值:
- 纯右值是一个表达式,其求值初始化一个对象或计算一个运算符的操作数的值,如它出现的上下文所指定,或者是一个类型为 cv void 的表达式。
您的案例似乎正在初始化一个对象。出于这个原因,我会说这是一个纯右值。