Move Semantics with unique_ptr

后端 未结 2 808
轮回少年
轮回少年 2021-02-14 01:47

I am using Visual Studio 2012 Update 2 and am having trouble trying to understand why std::vector is trying to use the copy constructor of unique_ptr. I have looked at similar

相关标签:
2条回答
  • 2021-02-14 02:22

    The push_back() function takes its argument by value. Therefore, an attempt is made to either copy-construct the argument of push_back() (if you are passing an lvalue), or to move-construct it (if you are passing an rvalue).

    In this case, o is an lvalue - because named objects are lvalues - and rvalue references cannot bind to lvalues. Therefore, the compiler cannot invoke your move constructor.

    In order to have your object moved, you have to write:

    s.push_back(std::move(o));
    //          ^^^^^^^^^
    

    What surprises me in this case is that it seems VC11 generated a copy-constructor for MyObject implicitly without defining it as deleted (judging from the error you posted). This should not be the case, since your class declares a move constructor. Per Paragraph 12.8/7 of the C++11 Standard, in fact:

    If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4)

    I must conclude that while the error you are getting is correct - because you are not passing an rvalue to push_back() - VC11 is not fully compliant here.

    0 讨论(0)
  • 2021-02-14 02:38

    MyObject o; defines o to be an object. Which means it's a l-value. Doing s.push_back(o); then invokes the l-value overload of push_back() (it has no other choice), which tries to create a copy.

    Since your class is noncopyable, you have to move the object into the vector:

    for (int i = 0; i < 5; ++i)
    {
        MyObject o;
        s.push_back(std::move(o));
    }
    
    0 讨论(0)
提交回复
热议问题