2
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。(上面上下文中的任何例子都会让我明白这一点)。

4

2 回答 2

3

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

我认为您在变量的声明类型与由变量名称组成的表达式的类型和值类别之间混淆了。

decltype(Wrapobj)MyClass&&. 当有人说“Wrapobj是一个右值引用”时,他们是在谈论声明的类型。但是Wrapobj在表达式中使用时,它具有类型MyClass和值 category lvalue

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

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

的返回值GetObj()是一个临时对象。该标准实际上并没有指定临时对象的存储持续时间,尽管常见的实现使用堆栈(类似于自动对象)。我认为 C++17 可能正在改进该领域的标准措辞。

于 2016-11-07T06:11:03.130 回答
-1

这些答案将有助于...

右值引用是否允许悬空引用?

什么是 rvalues、lvalues、xvalues、glvalues 和 prvalues?

xvalues、glvalues和prvalues的真实例子?

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

    return std::move(Wrapobj);
}

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

Wrapobj是对 GetObj() 返回的纯右值的右值引用。该 prvalue 的生命周期延长到 rvalue 引用的生命周期Wrapobj,因此可以访问.i = 1

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

Wrapobj的引用对象具有自动存储,并且会在 WrapperOfGetObj 完成时销毁。

3)当xvalue变成glvalue以及当它变成rvalue时。(上面上下文中的任何例子都会让我明白这一点)。

xvalue总是glvalues。glvalues 只是所有'xvalues'和所有'lvalues'的联合,意味着“有身份”。xvalues 也总是 rvalues,它只是所有“xvalues”和所有“prvalues”的并集,意味着“可以移动”。

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

当您std::move(Wrapobj)从 WrapperOfGetObj() 返回时,您正在从std::move.

于 2016-11-06T16:26:51.547 回答