美文网首页
C++值类别

C++值类别

作者: delta1037 | 来源:发表于2020-04-30 18:59 被阅读0次

    每个C++表达式(带有操作数的操作符、字面量、变量名等)可按照两种独立的特性加以辨别:类型值类别 (value category)。每个表达式都具有某种非引用类型,且每个表达式只属于三种基本值类别中的一种:纯右值 (prvalue)亡值 (xvalue)左值 (lvalue)

    值类别关系图 - 图源参考文献2

    一、左值

    左值 (lvalue):如此称呼的历史原因是,左值可以出现于赋值表达式的左边
    描述:能够用&取地址的表达式是左值表达式,从值类别关系图上可以看出来是非亡值的泛左值。
    举例:

    • 函数名和变量名(实际上是函数指针和具名变量,具名变量如std::cinstd::endl等)
    • 返回类型为左值引用的函数调用或重载运算符表达式(std::getline(std::cin, str)、std::cout<< 1
    • 内建的前置自增与前置自减表达式(++i/--i
    • 由赋值运算符或复合赋值运算符连接的表达式(a=b、a+=b、a%=b
    • 解引用表达式*p
    • 字符串字面值(字符串常量)(如:"abc" == "bcd"

    二、纯右值

    纯右值 (prvalue):“纯 (pure)”的右值
    描述:求值符合下列之一的表达式:

    • 计算某个运算符的操作数的值(这种纯右值没有结果对象
    • 初始化某个对象或位域(称这种纯右值有一个结果对象)。所有类和数组的纯右值都有结果对象,即使它被舍弃也是如此。在某些语境中,将发生临时量实质化,以创建作为其结果对象的临时量

    举例:

    三、亡值

    亡值 (xvalue):(“将亡 (expiring)”的值)是代表其资源能够被重新使用的对象或位域的泛左值

    举例:

    • 返回类型为对象的右值引用的函数调用或重载运算符表达式(std::move(x))
    • 内建的下标表达式,其操作数之一是数组右值(a[n])
    • 对象成员表达式,其中 a 是右值且 m 是非引用类型的非静态数据成员(a.m)
    • 对象的成员指针表达式,(a.*mp)其中 a 为右值且 mp 为数据成员指针

    四、泛左值

    泛左值 (glvalue):(“泛化 (generalized)”的左值)是其求值确定一个对象、位域或函数的个体的表达式

    描述:泛左值包括左值和亡值

    • 泛左值可以通过左值到右值、数组到指针或函数到指针隐式转换转换成纯右值。
    • 泛左值可以是多态的:其所标识的对象的动态类型不必是该表达式的静态类型。
    • 泛左值可以具有不完整类型,只要表达式中容许。

    五、右值

    右值 (rvalue):(如此称呼的历史原因是,右值可以出现于赋值表达式的右边)是纯右值或者亡值

    描述:

    • 右值不能被取地址:&int()、&i++[3]、&42 及 &std::move(x) 是非法的。
    • 右值不能用作内建赋值运算符及内建复合赋值运算符的左操作数。
    • 右值可以用于初始化 const 左值引用,这种情况下该右值所标识的对象的生存期被延长到该引用的作用域结尾。
    • 右值可以用于初始化右值引用,这种情况下该右值所标识的对象的生存期被延长到该引用的作用域结尾。
    • 当被用作函数实参且该函数有两种重载可用,其中之一接受右值引用的形参而另一个接受 const 的左值引用的形参时,右值将被绑定到右值引用的重载之上(从而,当复制与移动构造函数均可用时,以右值实参将调用其移动构造函数,复制和移动赋值运算符与此类似)。

    六、参考文献

    【1】zh.cppreference.com/w/cpp/language/value_category
    【2】话说C++中的左值、纯右值、将亡值

    相关文章

      网友评论

          本文标题:C++值类别

          本文链接:https://www.haomeiwen.com/subject/jdptghtx.html