gpt4 book ai didi

c++ - 右值、左值和正式定义

转载 作者:IT老高 更新时间:2023-10-28 23:19:12 25 4
gpt4 key购买 nike

人们在听到这个时感到困惑

int&& x

x 具有右值引用类型,但 x 是左值。误解源于标识符和表达式是不同的事物,类型和值类别也是如此。此外,表达式的类型“在任何进一步分析之前进行调整”,“rvalue”和“lvalue”这两个词可以出现在类型名称和值类别名称中。

我想澄清正式的定义。假设我们有一个函数:

1 | void f(int&& x) {           
2 | ... = x;
3 | ... = std::move(x);
4 | }

下列说法正确吗?

  1. 在第 1 行中,x 是一个标识符(id 表达式),用于命名函数参数。它的类型是 int&&,这是 decltype(x) 返回的类型。 x 不是表达式,没有值类别。
  2. 在第 2 行中,x 是一个表达式。类型调整前其类型为int&&,类型调整后为int。值类别是左值。
  3. 在第 3 行中,std::move(x) 是一个表达式。调整前的类型为int&&,调整后为-int。值类别是 xvalue。
  4. 当我们说 x 具有右值引用类型时,我们要么将 x 的类型称为标识符,要么将 x 的类型称为code> 作为类型调整前的表达式。
  5. cppreference.com 的语句“每个表达式都有一些非引用类型,并且每个表达式恰好属于三个主要值类别之一”中的单词“类型”指类型调整后的类型。
  6. 当斯科特迈耶斯 writes “如果表达式的类型是左值引用(例如,T&const T& 等),则该表达式是左值。” he指的是调整前的类型,第二个单词“lvalue”指的是值类别。

最佳答案

首先是一些初步的段落:

[basic]

3 An entity is a value, object, reference, function, enumerator, type, class member, template, template specialization, namespace, parameter pack, or this.

[dcl.type.simple]

4 The type denoted by decltype(e) is defined as follows:

  • if e is an unparenthesized id-expression or an unparenthesized class member access ([expr.ref]), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;

  • otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;

  • otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

  • otherwise, decltype(e) is the type of e.

[dcl.ref]

1 In a declaration T D where D has either of the forms

& attribute-specifier-seqopt D1 && attribute-specifier-seqopt D1

and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of the identifier of D is “derived-declarator-type-list reference to T.”

[expr]

5 If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.

[expr.prim.general]

8 An identifier is an id-expression provided it has been suitably declared (Clause [dcl.dcl]). The type of the expression is the type of the identifier. The result is the entity denoted by the identifier. The result is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise.

[expr.call]

10 A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.

现在我们可以回答您的问题。

In the line 1, x is an identifier (id-expression) that names a function parameter. Its type is int&&, and this is the type that decltype(x) returns. x is not an expression and has no value category.

是的。 x在声明中不是表达式。但作为 decltype 的论据一个表达式。但是,它遇到了 decltype 的特殊情况。的第一个项目符号,因此 x 命名的标识符的类型推导出来,而不是 x 的类型作为表达式。

In the line 2, x is an expression. Before type adjustment its type is int&&, and after the type becomes int. The value category is lvalue.

是的。

In the line 3, std::move(x) is an expression. Its type before adjustment is int&&, after - int. The value category is xvalue.

是的。

When we say that x has rvalue reference type, we refer either to the type of x as an identifier, or to the type of x as an expression before type adjustment.

是的。

The word "type" in the statement "Each expression has some non-reference type, and each expression belongs to exactly one of the three primary value categories" at cppreference.com refers to the type after type adjustment.

是的。

When Scott Meyers writes "If the type of an expression is an lvalue reference (e.g., T& or const T&, etc.), that expression is an lvalue." he refers to the type before adjustment, and the second word "lvalue" refers to the value category.

无法确定 Scott Meyers 写这篇文章时的意思,但这是对符合标准的词语的唯一解释,是的。

关于c++ - 右值、左值和正式定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56716647/

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