Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从函数返回时的右值引用行为_C++_C++11_C++14_Rvalue Reference - Fatal编程技术网

C++ 从函数返回时的右值引用行为

C++ 从函数返回时的右值引用行为,c++,c++11,c++14,rvalue-reference,C++,C++11,C++14,Rvalue Reference,在以下代码中: class Myclass { public: Myclass() = default; ~Myclass() = default; Myclass(Myclass&&) = default; Myclass& operator=(Myclass&&) = default; Myclass(const Myclass&) = delete; Myclass&

在以下代码中:

class Myclass
{    
public:
    Myclass() = default;
    ~Myclass() = default;

    Myclass(Myclass&&) = default;
    Myclass& operator=(Myclass&&) = default;

    Myclass(const Myclass&) = delete;    
    Myclass& operator=(const Myclass&) = delete;
};

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

Myclass WrapperOfGetObj()
{
    Myclass&& Wrapobj = GetObj();

    return Wrapobj;
}

int main()
{
    return 0;
}
编译时,函数
WrapperOfGetObj
return
Wrapobj
上出现错误。错误是

'Myclass::Myclass(const Myclass&)':尝试引用已删除的函数

这意味着它正试图调用
deleted
copy构造函数。正如我所知,
Wrapobj
是左值,当返回它时,它的行为应该与
GetObj
方法中的
obj
相同,即在
返回时调用move构造函数。
那么它为什么要寻找复制构造函数呢?这里我遗漏了什么?

这里的问题是(正如T.C.在注释部分总结的那样)
wrapbj
是一个引用,而不是一个对象,因此隐式移动(即将返回的左值视为右值)在这种情况下不适用(请参阅)

您可以通过以下方式解决此问题:

Myclass Wrapobj = GetObj();
而不是当前的:

Myclass&& Wrapobj = GetObj();

或者在返回时显式地
std::move()
ing
Wrapobj
。我个人建议选择第一个选项。

您需要使用
std::move()
显式生成右值。对于这个主题来说,这可能是一个很好的额外阅读。表达式
Wrapobj
是类型为
MyClass
的左值;表达式从来没有引用类型(在[expr]/5调整之后)。问题是隐式移动只适用于自动存储持续时间([class.copy]/32)的对象,而引用不是对象。此外,“如果返回语句中的命名左值的类型与函数的返回类型不同,则编译器不会将其视为右值”,这是不正确的,因为。@t.C.:这在标准中已经阐明了吗?在我更活跃的时候,我曾经相信这一点,但后来我想这可能取决于解释(见)。还有最后一句话吗?无论如何,我会尝试更准确地改写它。我认为当它立即消失时,考虑预调整类型是非常有用的(因此,括号限定符)。@ T.C:我写了一个。