繁体   English   中英

是否将rvalue作为参数传递给函数内的左值?

[英]is rvalue passed as parameter treated as lvalue inside the function?

我有一个View和一个Shape类,其中View“拥有”它的Shape对象。 我将其实现为unique_ptr的向量。 在函数View :: add_shape(std :: unique_ptr && shape)中,我仍然需要在rvalue参数上使用std :: move来进行编译。 为什么? (使用GCC 4.8)

#include <memory>
#include <vector>
using namespace std;

class Shape { };
class View
{
  vector<unique_ptr<Shape>> m_shapes;
  public:
  void add_shape(unique_ptr<Shape>&& shape)
  { 
    m_shapes.push_back(std::move(shape));// won't compile without the std::move
  }
};


int main()
{
  unique_ptr<Shape> ups(new Shape);
  View v;
  v.add_shape(std::move(ups));
}

是的,参数的rvalue引用仅用于从调用者的角度选择函数,它的行为类似于函数内的左值引用。

原因是您只允许移动一次值,并且认为自动保持参数的rvalue-ness被认为太危险了。 参数类型表示此函数接受rvalue,并通过提供实际移动值的实现来潜在地使用它。 通过重载这个版本的方法可以用于支持非移动版本。 或者它只是说该函数需要一个右值。

在函数的实现中发生了什么是另一回事。 考虑像这样的方法

void add_shape_twice(unique_ptr<Shape>&& shape)
{ 
  m_shapes.push_back(shape);
  m_shapes.push_back(shape);
}

如果作为参数的shape仍然是右值参考:您可能会意外地将值移动两次。 因为在现实世界中,函数可能更长并且多次引用参数(明确地或在循环或包扩展中)是很常见的,所以错误的可能性将是巨大的。

即使我们都知道它并且永远不会忘记它,它也意味着我们需要抛弃rvalue-ness,这会使代码非常笨拙。 我们会不断添加和删除 rvalue-ness。

是的,在进入rvalue引用现在具有名称的函数之后,所以它被视为左值。 因此你必须move它。

void add_shape(unique_ptr<Shape>&& shape)
                                   ^^^^^

或按值传递:

void add_shape(unique_ptr<Shape> shape)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM