Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
397 views
in Technique[技术] by (71.8m points)

c++ - is rvalue passed as parameter treated as lvalue inside the function?

I have a View and a Shape class where the View "owns" its Shape objects. I am implementing this as a vector of unique_ptr. In the function View::add_shape(std::unique_ptr&& shape), I still need to use std::move on the rvalue parameter to make it compile. Why? ( using 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));
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes, the rvalue reference from the parameter is only used to select the function from the caller's perspective, it behaves like an lvalue reference inside the function.

The reason is that you are only allowed to move a value once and it was deemed too dangerous to keep the rvalue-ness of a parameter automatically. The parameter type indicates that this function accepts an rvalue and makes potentially use of this by providing an implementation that actually moves the value. By overloading this version of the method can be used in favor of the non-moving version. Or it simply says that the function requires an rvalue.

What happens in the implementation of the function is another thing. Consider a method like

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

if shape as a parameter would remain an rvalue reference: You would have accidentally moved the value twice. Since in the real world functions may be longer and it's quite common to refer to the parameters multiple times (either explicitly or within a loop or pack expansion), the potential for errors would be enormous.

Even if we would all be aware of it and never forget about it, it would also mean that we need to cast away rvalue-ness and this would make the code quite clumsy. We would constantly be adding and removing rvalue-ness.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...