首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11/14中的“`xvalue`”行为

C++11/14中的“`xvalue`”行为
EN

Stack Overflow用户
提问于 2016-11-06 15:22:08
回答 2查看 488关注 0票数 2
代码语言:javascript
复制
class Myclass
{    
public:
    Myclass() = default;
    ~Myclass() = default;
    Myclass(Myclass&&) = default;
    Myclass& operator=(Myclass&&) = default;

    Myclass(const Myclass&) = delete;

    Myclass& operator=(const Myclass&) = delete;
    int i = 0;
};

Myclass GetObj()
{
    Myclass obj;    
    return obj;
}

Myclass WrapperOfGetObj()
{
    Myclass&& Wrapobj = GetObj();
    Wrapobj.i = 1; // Will it work?

    return std::move(Wrapobj);
}

int main()
{
    return 0;
}

我有几个问题: 1)在WrapperOfGetObj函数中,Wrapobjxvalue,所以我可以将值分配给它的任何成员(xvalue -即将过期!)

2) xvalue的存储是什么?这不是自动存储吗?

3)当xvalue变成glvalue时,当它变成rvalue时。(在上述上下文中的任何示例都会向我说明这一点)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-07 06:11:03

表达式Wrapobj是一个lvalue。所有命名变量都是lvalue。

我认为您混淆了变量的声明类型,以及包含变量名称的表达式的类型和值类别。

decltype(Wrapobj)给了MyClass&&。当有人说"Wrapobj是一个rvalue引用“时,他们指的是声明的类型。但是在表达式中使用Wrapobj时,它有类型MyClass和值类别lvalue

不存在带有引用类型的表达式。此外,表达式的类型和值类别与表达式是否表示临时对象没有直接关系。

对于您的问题2:"xvalue“是表达式的值类别。表达式没有存储空间。对象有存储空间。引用可以使用存储,也可以不使用存储(未指定)。一定要区分引用的存储和它所引用的对象的存储。

GetObj()的返回值是一个临时对象。虽然通用实现使用堆栈(类似于自动对象),但该标准实际上并没有为临时对象指定存储期限。我认为C++17可能正在改进该标准在这方面的措辞。

票数 3
EN

Stack Overflow用户

发布于 2016-11-06 16:26:51

这些答案会有帮助..。

Do rvalue references allow dangling references?

What are rvalues, lvalues, xvalues, glvalues, and prvalues?

Real life examples of xvalues, glvalues, and prvalues?

代码语言:javascript
复制
Myclass WrapperOfGetObj()
{
    Myclass&& Wrapobj = GetObj();
    Wrapobj.i = 1; // Will it work?

    return std::move(Wrapobj);
}

1)在WrapperOfGetObj函数中,Wrapobj是xalue,所以我可以将值分配给它的任何成员(xvalue -即将过期!)

Wrapobj是对GetObj()返回的prvalue的rvalue引用。该prvalue的生存期已扩展到rvalue引用Wrapobj的生存期,因此访问.i = 1很好。

2) xvalue的存储是什么?这不是自动存储吗?

Wrapobj的引用对象具有自动存储功能,当WrapperOfGetObj完成时将销毁。

3)当xvalue变成glvalue时,当它变成rvalue时(上述上下文中的任何示例都会向我说明这一点)。

xvalue总是很有价值的。格值只是所有‘x值’和所有‘lvalue’的结合,意思是“有身份”。X值也总是rvalue,它只是所有“xvalue”和所有“prvalue”的结合,意思是“可以移动”。

因此,在上面的示例中,Wrapobj是一个glvalue (因为它具有标识)、一个rvalue (因为它可以移动)和一个xvalue (因为它既是可移动的,又具有标识)。

当您从std::move(Wrapobj) ()返回WrapperOfGetObj()时,您将从std::move返回的xvalue构造一个新的prvalue。

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

https://stackoverflow.com/questions/40450988

复制
相关文章

相似问题

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