gpt4 book ai didi

c++ - 阐明表达式的值类别

转载 作者:行者123 更新时间:2023-12-04 14:50:58 25 4
gpt4 key购买 nike

2010 年,C++ 的创始人 Bjarne Stroustrup 撰写了论文 “New” Value Terminology他在其中解释了 C++11 标准中引入的表达式的值类别*(左值xvalueprvalue,以及它们的概括 glvaluervalue):

There were only two independent properties:

  • “has identity” – i.e. and address, a pointer, the user can determine whether two copies are identical, etc.
  • “can be moved from” – i.e. we are allowed to leave to source of a “copy” in some indeterminate, but valid state

This led me to the conclusion that there are exactly three kinds of values (using the regex notational trick of using a capital letter to indicate a negative – I was in a hurry):

  • iM: has identity and cannot be moved from
  • im: has identity and can be moved from (e.g. the result of casting an lvalue to a rvaluereference)
  • Im: does not have identity and can be moved from

The fourth possibility (“IM”: doesn’t have identity and cannot be moved) is not useful in C++ (or, I think) in any other language.In addition to these three fundamental classifications of values, we have two obvious generalizations that correspond to the two independent properties:

  • i: has identity
  • m: can be moved from

2015年,时任C++标准编辑的Richard Smith撰写了论文Guaranteed copy elision through simplified value categories他在其中解释了 C++17 标准中引入的表达式值类别的改写**:

However, these rules are hard to internalize and confusing -- for instance, an expression that creates a temporary object designates an object, so why is it not an lvalue? Why is NonMoveable().arr an xvalue rather than a prvalue? This paper suggests a rewording of these rules to clarify their intent. In particular, we suggest the following definitions for glvalue and prvalue:

  • A glvalue is an expression whose evaluation computes the location of an object, bit-field, or function.
  • A prvalue is an expression whose evaluation initializes an object, bit-field, or operand of an operator, as specified by the context in which it appears.

That is: prvalues perform initialization, glvalues produce locations.

Denotationally, we have:

  • glvalue :: Environment -> (Environment, Location)
  • prvalue :: (Environment, Location) -> Environment

So far, this is not a functional change to C++; it does not change the classification of any existing expression. However, it makes it simpler to reason about why expressions are classified as they are:

struct X { int n; };
extern X x;
X{4}; // prvalue: represents initialization of an X object
x.n; // glvalue: represents the location of x's member n
X{4}.n; // glvalue: represents the location of X{4}'s member n;
// in particular, xvalue, as member is expiring

基本上,Smith 只是将 Stroustrup 对纯右值的定义从“没有恒等式”改写为“执行初始化”。

我仍然不清楚以下事情(所以这些是我的问题):

  1. Smith 符号“glvalue::Environment -> (Environment, Location)”和“prvalue::(Environment, Location) -> Environment”的含义。
  2. Smith 的表达式 X{4}.n 不是 C++17 标准下的纯右值的基本原理**,因为它执行完整的初始化对象 X{4}(称为“临时对象实现”),尤其是其子对象 n
  3. Smith 的表达式 X{4}.n 不是 C++11 标准下的纯右值的基本原理*,因为它表示 临时对象的子对象.

注意事项

* C++11 标准中表达式的值类别,[basic.lval/1] (大胆强调我的):

  • An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment expression) designates a function or an object. [ Example: If E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the result of calling a function whose return type is an lvalue reference is an lvalue. — end example ]
  • An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references ([dcl.ref]). [ Example: The result of calling a function whose return type is an rvalue reference is an xvalue. — end example ]
  • A glvalue (“generalized” lvalue) is an lvalue or an xvalue.
  • An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object ([class.temporary]) or subobject thereof, or a value that is not associated with an object.
  • A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. — end example ]

** C++17 标准中表达式的值类别,[basic.lval/1] (大胆强调我的):

  • A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
  • A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
  • An xvalue is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime). [ Example: Certain kinds of expressions involving rvalue references yield xvalues, such as a call to a function whose return type is an rvalue reference or a cast to an rvalue reference type.  — end example ]
  • An lvalue is a glvalue that is not an xvalue.
  • An rvalue is a prvalue or an xvalue.

最佳答案

  1. 这在评论中得到了很大程度的回答,但要详细说明:通过考虑“世界”的状态(从所有 RAM 开始),可以无副作用地表达任何命令式系统的语义) 作为函数的参数和作为函数返回值的(一部分)。此表示法表示计算左值从该环境中选择一个地址(对象的身份)(并可能更改它),而计算纯右值需要这样的位置并更改环境以包含已初始化的对象那里(可能有其他副作用)。
  2. X{4}.n 没有初始化 n(用什么,它自己?);它允许访问(识别)仅由 X{4} 建立的值(具体化以具有特定的 n 来识别)。
  3. 你对它的临时状态是正确的,但这只是使它成为一个右值;纯右值是一个右值,它也是一个xvalue。

关于c++ - 阐明表达式的值类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69125113/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com