首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪些表达式创建xvalue?

哪些表达式创建xvalue?
EN

Stack Overflow用户
提问于 2012-07-20 15:01:47
回答 4查看 6K关注 0票数 28

我正在努力理解C++11的概念。

我所说的标准草案:

xvalue (“eXpiring”值)也指对象,通常是在其生命周期结束时(例如,这样就可以移动其资源)。xvalue是涉及rvalue引用(8.3.2)的某些表达式的结果。示例:调用返回类型为rvalue引用的函数的结果是xvalue。-end实例

好的,那么产生xvalue的“特定类型的表达式”到底是什么?规范的这一部分没有详细说明这些表达式的列表。

我理解lvalue和prvalue (至少我认为,我理解)。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-07-26 01:43:28

在对第5节(C++11§5 non/6)的导言中有一个有用的非规范性说明:

[注:表达式如果为x值,则为:

  • 调用函数的结果,无论是隐式的还是显式的,其返回类型是对对象类型的rvalue引用,
  • 转换为对对象类型的rvalue引用,
  • 指定非引用类型的非静态数据成员的类成员访问表达式,其中对象表达式为xvalue,或
  • 一个.*指针到成员表达式,其中第一个操作数是一个xvalue,第二个操作数是指向数据成员的指针。

通常,此规则的效果是将命名rvalue引用视为lvalue,而对对象的未命名rvalue引用处理为rvalue;对函数的rvalue引用被视为lvalue,无论是否命名。-end注记]

搜索完第5节的其余部分,这个列表看起来是详尽无遗的。该列表后面是一个示例:

结构A{ int;};A& operator+(A,A);A& f();A& a;A& ar = static_cast(a); 表达式f()f().mstatic_cast<A&&>(a)a + a是xvalue。表达式ar是一个lvalue。

获得xvalue表达式有两种常见的方法:

  • 使用std::move移动对象。std::move对rvalue引用类型执行static_cast并返回rvalue引用。
  • 使用std::forward转发rvalue。函数模板中通常使用std::forward来实现函数参数的完美转发。 如果提供给函数模板的参数是rvalue,则参数类型将是rvalue引用,即lvalue。在这种情况下,std::forward对rvalue引用类型执行static_cast并返回rvalue引用。 (注意:如果提供给函数模板的参数是lvalue,则参数类型将是lvalue引用,std::forward将返回lvalue引用。)
票数 19
EN

Stack Overflow用户

发布于 2012-07-26 02:47:40

第5条描述了有效表达式的语法,为每个表达式语法列出了表达式为lvalue、xvalue或prvalue的条件。第5条中可能出现的x值的完整列表是:

5.2.2第10段:函数调用是.如果结果类型是对对象类型的rvalue引用,则为xvalue。

(在标准的技术语言中,“对象类型”并不意味着与“类类型”相同。“对象类型”包括基本类型、指针和数组,并且只排除函数类型。对函数类型的rvalue引用始终被视为lvalue,而不是xvalue。)

返回rvalue引用的最显著的函数当然是std::move,有时还包括std::forward

5.2.5第4段:如果E2是非静态数据成员.如果E1是xvalue,那么E1.E2就是xvalue。

(另一方面,数据成员查找E1->E2总是一个lvalue。)

类似地,如果E1是xvalue,那么数据成员查找E1.*E2就是xvalue:

5.5第6段:第二个操作数是指向数据成员的指针的.*表达式的结果与其第一个操作数相同的值类别(3.10)。

适用于各种类型的铸件:

  • dynamic_cast<Type>(expr):5.2.7第2段
  • static_cast<Type>(expr):5.2.9第1段
  • reinterpret_cast<Type>(expr):5.2.10第1段
  • const_cast<Type>(expr):5.2.11第1段
  • (Type) expr:5.4第1段

表达式是xvalue当且仅当Type是对对象类型的rvalue引用时。Type(expr)也是如此,因为

5.2.3第1款:如果类型名称后面括号中的表达式列表是单个表达式,则类型转换表达式与相应的cast表达式(5.4)等效(定义为定义,定义为定义)。

(另一方面,Type{expr}始终是一个prvalue。)

关于条件运算符的第5.16节最后说,如果B和/或C是xvalue,A ? B : C有时可以是xvalue。但完整的规则很难概括。

如果表达式最后调用用户定义的重载运算符函数,那么第5.2.2节适用于该表达式,而不是描述内置运算符行为的表达式。(请参阅示例@James posted中的表达式a + a。)

票数 6
EN

Stack Overflow用户

发布于 2021-03-02 12:26:09

就像你提到的,

xvalue (“eXpiring”值)也指对象,通常是在其生命周期结束时(例如,这样就可以移动其资源)。

焦点:objectbe movedend lifetime

下面是一个示例:

代码语言:javascript
复制
void move_test(){
    std::string s = "I'm here!";
    std::string m  =  std::move(s);  // move from <s> to <m>
    // s is now in an undefined, but valid state; 
    std::cout << "s=" << s << "; &s=" << &s << std::endl;
}

通过移动,我们可以将一个命名的值( lvalue,这里是s)转换为rvalue(即std::move(s))。更具体地说,因为它不能是一个prvalue (它有一个名称!换句话说,它有一个身份),它最终是一个xvalue

xvalue总是提供C++移动语义。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11581903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档