Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Let's say I got a Foo class containing an std::vector constructed from std::unique_ptr objects of another class, Bar.

typedef std::unique_ptr<Bar> UniqueBar;

class Foo {
    std::vector<UniqueBar> bars;
public:
    void AddBar(UniqueBar&& bar);
};

void Foo::AddBar(UniqueBar&& bar) {
    bars.push_back(bar);
}

This one results in a compilation error (in g++ 4.8.1) saying that the the copy constructor of std::unique_ptr is deleted, which is reasonable. The question here is, since the bar argument is already an rvalue reference, why does the copy constructor of std::unique_ptr is called instead of its move constructor?

If I explicitly call std::move in Foo::AddBar then the compilation issue goes away but I don't get why this is needed. I think it's quite redundant.

So, what am I missing?

See Question&Answers more detail:os

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

1 Answer

Basically, every object which has a name is an lvalue. When you pass an object to a function using an rvalue reference the function actually sees an lvalue: it is named. What the rvalue reference does, however, indicate is that it came from an object which is ready to be transferred.

Put differently, rvalue references are assymmetrical:

  • they can only receive rvalues, i.e., either temporary objects, objects about to go away, or objects which look as if they are rvalues (e.g., the result of std::move(o))
  • the rvalue reference itself looks, however, like an lvalue

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...