c++中的static_cast转换的问题

新手上路,请多包涵
int &&rri = 42;
int &&rri1 = rri;

rri是一个左值,rri1不能绑定一个左值。

int&& rri1 = static_cast<int&&>(rri);

但是为什么static_cast转换后就可以了呢?static_cast转换后的类型不还是int&&的吗?

阅读 3.3k
2 个回答

左值 / 右值 是 表达式的值的属性,不是类型的属性,不与类型一一对应。它是由表达式的值的类型,与表达式的形式(得到这个值的过程)共同决定的。

// 42 的类型是 int ,这是一个 int 字面量,因而是右值
int &&rri = 42;
int a = 42;
// a 的类型也是 int, 但它是一个变量,因而是左值
int &&rri2 = a; // ERROR
// a + 1 的类型还是 int,它是 + 运算符的结果,为右值
int &&rri3 = a + 1;

rri 本身作为一个表达式,是一个左值。

单独由一个变量组成的表达式叫做 id-expression (unqualified-id) 。unqualified-id 为函数、变量、类成员变量结果为左值;其它为右值(比如 enumerator)。 rri 是一个变量,结果为左值。

8.1.4.1 Unqualified names
1) ...... The expression is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise; ......

static_cast<int&&>(rri) 的类型虽然与 rri 相同,但是它是一个右值。

static_cast<T>(v) ,仅当 T 为 左值引用 或 对函数的右值引用 时,结果为左值。其余情况均为右值。

8.2.9 Static cast
1) The result of the expression static_cast<T>(v) is the result of converting the expression v to type T. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue. ......

C++ 标准里对每一种表达式形式,都详细定义结果何时为左值、何时为右值。

引用来自 C++17 draft n4659

static_cast之所以可以是因为表达式static_cast<int&&>(rri)的value category是xvalue。相比之下表达式rri是lvalue。这两个表达式的类型相同,均为int。

引用初始化是否合法取决于被初始化的引用类型和用于初始化的表达式的类型以及它的value category
value category是表达式的一个属性(也可以理解成所有表达式都可以按value category归为三类)。
使用表达式的类型进行分析时,需要首先去掉它的所有引用,即如果直觉上某表达式的类型是int &&,那么分析时其类型要按int处理。

value category一种有五种
三种primary category: lvalue, prvalue, xvalue
两种mixed category: glvalue(lvalue, xvalue), rvalue(prvalue, xvalue)

只有prvalue或xvalue可以用于初始化右值引用,也就是rvalue。
因此要确定一个表达式是否能初始化某个引用,我们需要确定这个表达式属于哪个value category

int &&rri = 42; \\ 表达式 42 是int rvalue(prvalue),可以初始化右值引用
int &&rri1 = rri; \\ 表达式 rri 是int lvalue,不可以初始化右值引用
int &&rri2 = static_cast<int&&>(rri); \\ 表达式`static_cast<int&&>(rri)`是int rvalue(xvalue),可以初始化右值引用

PS:更加完整的分析还要考虑到隐式转换,但你给出的例子几乎不涉及隐式转换,这部分就略去了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题