value_category (cppreference.com 文档翻译) (校正 by 囧多)

原文链接: http://en.cppreference.com/w/cpp/language/value_category

Value categories:

Each C++ expression (an operator with its arguments, a literal, a variable name, etc) is characterized by two
independent properties: a type and a value category. Each expression has some non-reference type, and each
expression belongs to exactly one of the three primary value categories.

每个C++表达式(带有参数的运算符, 一个字面值, 一个变量名, 等等) 由两个属性来定性:
一个 type 表达式类型 和 一个 value category 值分类. 每个表达式都有一个或者
多个非引用类型, 每一个表达式都仅属于3大值分类中的一类.

Primay categories 主要类别

lvalue 左值

An lvalue is an expression that identifies a non-temporary object or a non-member function.
一个 lvalue 表示 一个非临时对象或非成员函数的表达式.

The following expressions are lvalues:
以下表达式为左值:

  • The name of a variable or function in scope, regardless of type, such as std::cin or std::endl. Even if the
    variable’s type is rvalue reference, the expression consisting of its name is an lvalue expression.

作用域中的变量或者函数名称, 无论其类型, 例如 std::cin 或 std::endl.
甚至变量的类型是右值引用, 包含其名字的表达式是一个左值表达式

Faq: 1. 右值引用的左值表达式?

  • Function call or overloaded operator expression if the function’s or overloaded operator’s return
    type is an lvalue reference, such as std::getline(std::cin, str) or std::cout << 1 or str1 = str2
    or ++iter(assuming the operators aren’t overloaded to return by value)

函数调用 或者 重载运算符表达式(如果其函数或者重载运算符返回的类型是左值引用,
例如 std::getline(std::cin, str) or std::cout << 1 or str1 = str2 or
++iter(假设运算符不能被重载为以值返回)

  • Built-in pre-increment and pre-decrement, dereference, assignment and compound assignment, subscript (except
    on an array xvalue), member access (except for non-static non-reference members of xvalues, member
    enumerators, and non-static member functions), member access through pointer to data member if the left-hand
    operand is lvalue, comma operator if the right-hand operand is lvalue, ternary conditional if the second and third
    operands are lvalues.

内建的 前置的增量和前置的减量, 解引用, 赋值和复合赋值, 下标符(除了在数组 array 的xvalue), 成员访问(除了 xvalue的非静态 非引用成员,
成员枚举, 和非静态成员函数), 通过指向数据成员的访问作如果是左操即左值, 如果是右操作的逗号操作符即左值, 三目条件下的第二个和第三个操作数即左值.

Faq:
1.解引用是什么
2.xvalue是什么
3. 成员访问 x.i = 1; //
指向数据成员 x->i = 1; //

  1. 逗号操作符?

  2. 三目条件 a > 1? a:b = 3; // a和b是左值, 是这个意思吗

  • Cast expression to lvalue reference type.
    转型表达式为左值引用类型?

  • String literal
    字符串常量

  • Function call expression if the function’s return type is rvalue reference to function type (rare) (since C++11)
    函数调用表达式, 如果函数返回的是右值引用为一个函数的类型(罕见用法)

  • Cast expression to rvalue reference to function. (since C++11)
    转型表达式为右值引用的函数?

Properties: 属性
– Same as glvalue (below)
与glvalue一样(参见下面)

  • Address of an lvalue may be taken: &++i(Assuming i has built-in type or
    the pre-increment operator is not overloaded to return by value)
    and &std::endl are valid expressions.
    像取左值地址的操作: &++i(假设 i 是内建的类型或者前缀的自增操作, 不能重载为值返回) 和 &std::endl 是合法的表达式

  • A modifiable lvalue may be used as the left-hand operand of the built-in assignment operator.
    可修改的左值可能用于内建的赋值运算符作为左操作数

  • An lvalue may be used to initialize an lvalue reference; this associates a new name with the object identified by
    the expression.
    一个右值可能用于左值引用的初始化; 该表达式里它使用一个新的名字将其对象关联起来.
    int j = 1;
    int &i = j; i即int j的引用

  • An lvalue can have incomplete type, where permitted by the expression
    表达式允许的条件下, 一个左值可以使不完整的类型.

rvalue 右值 (until C++11) prvalue (since C++11)

A prvalue (“pure” rvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not
associated with any object.
一个纯右值是一个临时对象(或子对象的) 或是一个不关联其他对象的值

The following expressions are prvalues:
– Literal (except string literal), such as 42 or true or nullptr.
字面量(除了字符字面量), 例如 42 , true, nullptr

  • Function call or overloaded operator expression if the function’s or the overloaded operator’s return type is not a
    reference, such as str.substr(1, 2) or str1 + str2
    函数调用或者重载表达式操作符(如果函数或者重载操作符的返回类型不是一个引用, 例如 str.substr(1,2) str1 + str2

  • Built-in post-increment and post-decrement , arithmetic and logical operators, comparison operators, address-of
    operator, member access for a member enumerator, a non-static member function, or a non-static non-reference
    data member of an rvalue, member access through pointer to a data member of rvalue or to a non-static member
    function, comma operator where the right-hand operand is rvalue, ternary conditional where either second or third
    operands aren’t lvalues.
    内建的后增, 后减, 算术和逻辑操作符, 比较操作符,取址操作符, 右值的成员计数器, 非静态成员函数, 非静态的非引用数据成员的成员访问,
    通过指向右值的数据成员或者非静态成员函数的成员访问, 作为右手运算符的逗号 皆是右值, 三目条件的第二第三操作数不是左值.

  • Cast expression to any type other than reference type.
    (引用类型除外)的转型表达式

  • Lambda expressions, such as [](int x){return xx;} (since C++11)
    Lambda 表达式, 例如 [](int x){return x
    x;}

Properties: (属性)
– Same as rvalue (below)
与右值一样(见下文) 下文不是 xvalue吗, – -b 原文粗心啦?

  • a prvalue cannot be polymorphic: the dynamic type of the object it identifies is always the type of the expression.
    一个纯右值不可以是多态的: 识别对象的动态类型总是一个类型表达式

  • a non-class non-array prvalue cannot be const-qualified.
    非类非数组的纯右值不可能是 const 限制.

  • a prvalue cannot have incomplete type (except for type void, see below)
    一个纯右值不可能是不完整的类型(除了void, 见下面)

xvalue

An xvalue is an expression that identifies an “eXpiring” object, that is,
the object that may be moved from. The object identified by an xvalue
expression may be a nameless temporary, it may be a named object in scope,
or any other kind of object, but if used as a function argument, xvalue
will always bind to the rvalue reference overload if available.
一个xvalue 识别为 “满期”对象的表达式, “满期”对象 可以被移走. 被识别为xvalue表达式
的该对象可能是匿名的临时量, 可以是作用域中一个已命名的对象, 或其他类型, 但如果被用于
函数参数, 在重载允许下的条件下, xvalue 会绑定为右值引用

Only the following expressions are xvalues:
仅以下表达式是xvalue:
– A function call or overloaded operator expression if the function’s or
the overloaded operator’s return type is an rvalue reference to object type,
such as std::move(val)
一个函数调用或者重载操作符的表达式(如果函数或者重载操作符的返回值是对象类型的右值引用,
例如 std::move(val))

  • A cast expression to an rvalue reference to object type, such as
    static_cast<T&&>(val) or (T&&)val
    一个对对象类型右值引用的转型表达式, 例如
    static_cast<T&&> 或 (T&&)val

  • a non-static class member access expression, in which the object
    expression is an xvalue
    该对象的表达式为xvalue时, 其非静态类的成员访问表达式.

  • A pointer-to-member expression in which the first operand is an xvalue
    and the second operand is a pointer to data member.
    第一个操作数的指向成员的表达式是 xvalue, 且第二个操作数是一个指向数据成员的指针

Properties:
– Same as rvalue (below)
同 rvalue

  • Same as glvalue (below)
    同glvalue

Like prvalues, xvalues bind to rvalue references, but unlike prvalues,
an xvalue may be polymorphic, and a non-class xvalue may be cv-qualified.
类似纯右值, xvalue 绑定了右值引用, 但不像纯右值, xvalue 可以是多态, 非类型的xvalue可以是
const value限制

Mixed categories 混合分类

glvalue A glvalue (“generalized” lvalue) is an expression that is either an lvalue

or an xvalue.
glvalue 字面是广义的 lvalue, 即 lvalue 或者 xvalue 的表达式

Properties (note: these apply to pre-C++11 lvalues as well) 同样应用于 C++11 lvalue的标准

  • A glvalue may be implicitly converted to prvalue with lvalue-to-rvalue,
    array-to-pointer, or function-to-pointer implicit conversion. 一个 广义的左值 可以是隐式转换为纯右值(左值 -> 右值, 数组 -> 指针, 函数 -> 指针的隐式转换)

  • A glvalue may be polymorphic: the dynamic type of the object it identifies
    is not necessarily the static type of the expression.
    一个 广义的左值 可以是多态的: 对象的动态类型是非必须的静态类型表达式

rvalue An rvalue is an expression that is either a prvalue or an xvalue.

Properties (note, these apply to both xvalues and prvalues,
which means they apply to the pre-C++11 rvalues as well)
属性(应用于 xvalue 和 prvalue, C++11前的右值标准同样适用)

  • Address of an rvalue may not be taken: &int(), &i++[3], &42, and &std::move(val)
    are invalid.
    右值的地址不可以使用: &int(), &i++[3], &42 和 &std::move(val) 是非法的

  • An rvalue may be used to initialize a const lvalue reference, in which case the
    lifetime of the object identified by the rvalue is extended until the scope of
    the reference ends.
    一个右值可以作为const 左值引用的初始化(右值对象的生命周期到作用域末尾)

  • An rvalue may be used to initialize an rvalue reference, in which case the lifetime of
    the object identified by the rvalue is extended until the scope of the reference ends.
    一个左值可以作为右值引用的初始化(右值对象的生命周期直到作用域末尾)

  • When used as a function argument and when two overloads of the function are available,
    one taking rvalue reference parameter and the other taking lvalue reference to const
    parameter, rvalues bind to the rvalue reference overload (thus, if both copy and move
    constructors are available, rvalue arguments invoke the move constructor, and likewise
    with copy and move assignment operators).
    当作为一个函数参数, 以及函数可重载两种, 一个使用右值引用参数和另一个使用左值引用, 对const 参数引用,
    右值绑定到右值引用的重载(因此, 如果copy 和 move 构造允许下, 右值参数会调用move 构造函数, 并同样地
    运用到 copy 和 move 的赋值操作)

Special categories 特别的分类

Pending member function call

The expressions obj.func and ptr->func, where func is a non-static member function,
and the expressions obj.mfp and ptr->mfp where mfp is a pointer to member function,
are classified as prvalue expressions, but they cannot be used to initialize references,
as function arguments, or for any purpose at all, except as the left-hand argument of
a function call expression, e.g. (pobj->*ptr)(args).

表达式obj.func 和 ptr->func 中, 如果func 是非静态成员函数,以及表达式 obj.mfp 和 ptr->mfp
(mfp 是指向成员函数的指针) 被分类为纯右值表达式, 但他们不可以作为函数参数或者其他目的来初始化引用,
除了作为函数调用的表达式(作为左参数)

Void expressions

Function call expressions returning void, cast expressions to void, and throw-expressions
are classified as prvalue expressions, but they cannot be used to initialize references or
as function arguments. They can be used in some contexts (e.g. on a line of its own,
as the left argument of the comma operator, etc) and in the return statement in a function
returning void. In addition, throw-expressions may be used as the second and the third operands
of the conditional operator ?: (other void prvalues can only be used if appearing as both 2nd
and 3rd operands).
返回 void 的函数调用表达式, 转换void的转型表达式, 抛出的表达式 被分类为纯右值表达式, 但他们不可以用于初始化
引用或者作为函数参数. 它们可以使用在一些上下文中(例如, 作为逗号操作符的左参数的行) 和 返回void的函数中返回
状态. 另外, 抛出表达式可以使作为三目运算?:的第二或者第三操作数(其他的 void 纯右值只能被用于出现在第二和第三的操作数)

Bit fields 比特域

An expression that designates a bit field (e.g. s.x where s is an object of type
struct S { int x:3; };) is an lvalue expression (or xvalue if s is one): it may
be used on the left hand side of the assignment operator, but its address cannot
be taken and a non-const lvalue reference cannot be bound to it. A const lvalue
reference can be initialized from a bit-field lvalue, but a temporary copy of
the bit-field will be made: it won’t bind to the bit field directly.
设计为比特域的表达式(例如在 struct S{ int x:3;} 对象中) 是一个左值表达式(或者作为xvalue):
它可以作为赋值操作的左边, 但它的地址不可以被使用以及 非 cosnt 的左值引用不可以被绑定到它.
一个 cosnt 左值引用可以被比特域的左值初始化, 但一个比特域的临时拷贝可能会生成:并不是直接绑定 到比特域的.

原创文章,转载请注明: 转载自kaka_ace's blog

本文链接地址: value_category (cppreference.com 文档翻译) (校正 by 囧多)

发表评论

电子邮件地址不会被公开。 必填项已用*标注