我正在努力理解C++11的概念。
我所说的标准草案:
xvalue (“eXpiring”值)也指对象,通常是在其生命周期结束时(例如,这样就可以移动其资源)。xvalue是涉及rvalue引用(8.3.2)的某些表达式的结果。示例:调用返回类型为rvalue引用的函数的结果是xvalue。-end实例
好的,那么产生xvalue的“特定类型的表达式”到底是什么?规范的这一部分没有详细说明这些表达式的列表。
我理解lvalue和prvalue (至少我认为,我理解)。
发布于 2012-07-26 01:43:28
在对第5节(C++11§5 non/6)的导言中有一个有用的非规范性说明:
[注:表达式如果为x值,则为:
.*指针到成员表达式,其中第一个操作数是一个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().m、static_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引用。)发布于 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。)
发布于 2021-03-02 12:26:09
就像你提到的,
xvalue (“eXpiring”值)也指对象,通常是在其生命周期结束时(例如,这样就可以移动其资源)。
焦点:object,be moved,end lifetime
下面是一个示例:
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++移动语义。
https://stackoverflow.com/questions/11581903
复制相似问题