【问题标题】:Is it necessary to have a temporary or a literal to have an rvalue?是否需要临时或文字才能拥有右值?
【发布时间】:2026-02-08 10:35:01
【问题描述】:

This question 询问是否所有临时对象都是右值。

答案是否定的,因为如果我们考虑这个表达式:

const int &ri = 2 + 3;

然后,可以使用相同的临时(2 + 3),这里是一个右值 作为后续表达式中的左值:

const int *pi = &ri;

所以这个临时值不是(仅)一个右值。

则逻辑语句temporary ==> rvalue 为假。

但是,我们不能写

const int &ri = &(2 + 3); // illegal, 2 + 3 -> temporary -> rvalue

int *i = &4; // illegal, 4 is an rvalue (literal)

int foo();
int *i = &foo(); // illegal, foo() -> temporary -> rvalue

因此我的问题是,我们能否在某个表达式中生成一个右值,而无需 有一个临时的或文字的? rvalue ==> (temporary or literal) 是真的吗?

【问题讨论】:

    标签: c++ temporary rvalue


    【解决方案1】:

    产生临时对象的表达式右值。有一个特殊规则允许 const 引用和 r-value 引用绑定到 r-values,这将临时对象的生命周期延长到引用的生命周期(参见 12.2(5)),但这不会使临时对象-object 表达式,任何更少的 r 值。

    然而,一旦绑定到一个引用,引用变量本身就有一个名字,因此引用表达式是一个左-左值。

    不要混淆表达式、变量和对象。

    【讨论】:

    • 不要混淆表达式、变量和对象:正确。 l-valuer-value 适用于 表达式。临时变量不是 r-values,一个产生临时 is 的表达式是一个 r-value 表达式
    • @DavidRodríguez-dribeas:是的,确实——说得好。
    • 12.2(5) 所说的,确认temporary ==> rvalue 是假的,这没关系。但是我仍然没有一个例子表明rvalue ==> (temporary or literal) 是错误的。正如我对大卫所说,我不是在挑战,只是想了解是否可以做出这种断言 (rvalue ==> (temporary or literal))。谢谢。
    • @VincenzoPii:很多东西都是右值。例如,衰减的 C 数组名称。或this。或者某个静态转换的结果。
    • @VincenzoPii:除了这些示例之外,在需要 rvalue 的上下文中使用的 lvalue 表达式将被转换为 rvalue 与(显然命名):lvalue to rvalue conversionint a = 5; int b = 1+a;,子表达式 a 是一个 lvalue 将被转换为一个 rvalue,所以在这个特定的用法中 a 是一个 rvalue i>,正如我之前提到的:考虑 lvalue 是对真实对象的引用,而 rvalue 只是一个值(可能会或不会存储在对象)。
    【解决方案2】:

    rvaluelvalue 属性适用于表达式,而不适用于 objects。表达式可以是 lvaluervalue。过度简化产生值的表达式是 rvalue-expression,而产生对象的表达式是 lvalue-expressionlvaluervalue 的转换是 从对象中读取值的行为。

    产生临时值和文字的表达式都是右值表达式,它们代表而不是实际对象。

    在你的例子中:

    const int &ri = 2 + 3;
    const int *pi = &ri;
    

    表达式2+3 是一个右值表达式,用于初始化常量引用。根据该语言,这意味着将临时的生命周期延长到当前表达式之外,直到引用超出范围。之后,在第二个表达式中,子表达式ri 是一个lvalue-expression,它引用了临时对象,其生命周期已被延长。

    请注意,还有其他方法可以使用临时对象创建 右值表达式,例如调用产生引用的成员:

    struct test {
       test& thisTest() { return *this; }
    };
    test foo();
    ... foo().thisTest()
    

    子表达式foo() 是一个右值表达式,但表达式foo().thisTest() 是一个左值表达式。它们都引用了一个 临时 对象,该对象将在完整表达式的末尾消失。

    【讨论】:

    • 感谢您的回答。在您的最后一个示例中,您证明了 temporary ==> rvalue 是假的,但不是 rvalue ==> (temporary or literal) 是假的。是否有必要有一个临时或文字来屈服于右值?我不是在挑战你,只是愿意理解我们是否可以做出这样的断言:)。
    • @VincenzoPii:你没有抓住重点。 rvaluelvalue 适用于表达式,而不适用于 objects。非临时对象可以在需要 rvalue 的上下文中使用,这将触发 lvalue-to-rvalue 转换,您将使用对象作为 rvaluer/l-value 仅与涉及其中一个或另一个的表达式往往属于同一类型的临时/命名对象相关。举一个不相关的汽车示例:Jaguar/Volkswagen 与汽油/柴油无关,尽管只有一个 Jaguar 柴油车型(因此它们不是 100% 正交的)
    • 非常感谢您的解释,现在已经很清楚了!
    最近更新 更多