【问题标题】:xvalue from a class member access expression?来自类成员访问表达式的 xvalue?
【发布时间】:2017-06-27 12:20:17
【问题描述】:

所以我读了这个answer,因为我对何时将值视为 xvalue 感到困惑,例如当一个值即将到期/接近其生命周期结束时。可悲的是,我还是很迷茫。

不管怎样,报价单包括了这个:

  • 一个类成员访问表达式,指定一个非引用类型的非静态数据成员,其中对象表达式是 xvalue,或

  • .* 指向成员的表达式,其中第一个操作数是 xvalue,第二个操作数是指向数据成员的指针。

答案中还包含一个示例,但它没有举例说明(我猜)“一个 .* 指向成员的表达式,其中第一个操作数是 xvalue,第二个操作数是指向数据成员的指针。 ",那么谁能给我看一个?

但是,当执行f().mm 是一个xvalue 时,它​​确实举例说明了“指定非引用类型的非静态数据成员的类成员访问表达式,其中对象表达式是一个xvalue” /an rvalue 即将结束对我来说很有意义,因为 f() 返回一个 rvalue 引用。但是a是一个左值,那么如果你做了a.m,那不还是一个左值吗?

这里的困惑是这个成员访问表达式仍然指定了一个非引用类型的非静态数据成员。或者当说“其中对象表达式是一个xvalue”时,它是否意味着类对象必须是右值?

答案中提到的例子:

struct A {
    int m;
};

A&& operator+(A, A);
A&& f();
A a;
A&& ar = static_cast<A&&>(a);

【问题讨论】:

    标签: c++


    【解决方案1】:

    一个类成员访问表达式,指定一个非引用类型的非静态数据成员,其中对象表达式是一个 xvalue

    一个“类成员访问表达式”(即A.B形式的表达式)由两部分组成,一个对象表达式.之前的部分,@987654323 @) 和成员标识(.B 之后的部分)。

    因此,本段仅适用于 . 之前的部分是 xvalue。

    涉及.* 的示例与仅涉及. 的示例非常相似:

    struct A {
        int m;
    };
    int A::* p = &A::m;
    A&& f();
    
    std::cout << f().*p;
    

    表达式 f().*p 是一个 xvalue。

    【讨论】:

    • 谢谢 bud :) 所以为了确认,对象表达式必须是一个 xvalue,以便整个类成员访问表达式将被评估为一个 xvalue,对吗?在那种情况下,xvalue 是否意味着右值?虽然我已经阅读过 xvalues,但它们对我来说都像是右值。
    • @noflow xvalues 是右值
    • @noflow 从您发布的示例中,如前所述,它们都是 xvalues(以及 rvalues)。 rvalue 也可以是 prvalue,因此 notxvalue(例如,返回非引用对象的函数按值..你不能直接和立即访问该对象的属性 - 所谓的身份 - 除非你用它复制/初始化某些东西)。
    • @noflow 粗略的经验法则:左值 = 命名对象、动态对象、左值引用。 xvalue = 未命名的右值引用。 prvalue = 未命名的非引用对象。
    • @noflow 否。每个特定的左值都是要么左值 xvalue。永远不可能两者兼而有之。每个左值都是一个左值,但不一定反之亦然。每个 xvalue 都是一个左值,但不一定反之亦然。
    【解决方案2】:

    答案中还包含一个示例,但它没有举例说明(我猜)“一个 .* 指向成员的表达式,其中第一个操作数是 xvalue,第二个操作数是指向数据成员的指针。 ",那么谁能给我看一个?

    这是一个例子:

    struct C { int m = 42; };
    
    int C::* p = &C::m;
    C&& get_xvalue();
    
    std::cout << get_xvalue().*p; // get_xvalue() is an xvalue, p is a pointer to member
    

    一个类成员访问表达式,指定一个非引用类型的非静态数据成员,其中对象表达式是一个 xvalue

    这意味着访问非引用类型的非静态数据成员可以具有左值或 xvalue 值类别,具体取决于对象表达式的值类别(即点 . 之前的部分)。无论数据成员是否为引用类型,它始终是左值。

    例如

    struct C {
      std::string x;
    };
    
    C obj;
    std::move(obj.x) // rvalue and xvalue expression
    std::move(obj).x // In this case xvalue since `x` is not a reference type. Otherwise it would have been lvalue
    

    【讨论】:

    • 谢谢!但是基于表达式何时是 xvalue 的陈述,我没有看到任何地方提到 lvalue,那么 xvalues 如何与 lvalues 相关联?我确实看到了它们如何与右值相关联,因为右值引用接近其生命周期的尽头(即 xvalues,如果我错了,请再次纠正我),你帮助我理解了。
    • @noflow here's an example 最后一个概念 - 它们不是关联,规则可能会阻止表达式成为 xvalue,即全部
    • 嗯,但是当glvalues包含左值时,如果xvalues是rvalues和glvalues,你怎么能说xvalues和lvalues不关联?
    • 等一下,我想你误解了我在说什么......我在谈论链接的答案,其中包括关于表达式何时是 xvalue 并且我没有看到 lvalue 的引用在任何地方都提到过,那么如何将 xvalues 与左值相关联而不仅仅是右值?
    • @noflow 该图表仍然成立,因为我们在谈论 xvalue 表达式 this paragraph 是相关的,可能有助于消除更多疑虑
    猜你喜欢
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    相关资源
    最近更新 更多