1

The class Foo has an rvalue reference constructor that moves the contained vector of unique_ptrs so why does the following code give the following error, both with or without the std::move on the Foo() in main?

error C2280: 'std::unique_ptr<SomeThing,std::default_delete<_Ty>> &std::unique_ptr<_Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
class Foo{
public:
    Foo(){

    }
    Foo(Foo&& other) :
        m_bar(std::move(other.m_bar))
    {};

    std::vector<std::unique_ptr<SomeThing>> m_bar;
};

int main(int argc, char* argv[])
{
    Foo f;
    f = std::move(Foo());
    return 0;
}
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Edward J Brown
  • 333
  • 1
  • 5
  • 17

1 Answers1

4

This:

 f = std::move(Foo());

doesn't call the move constructor. It calls the move assignment operator. Furthermore, it's redundant, since Foo() is already an rvalue so that's equivalent to:

f = Foo();

Since you declared a move constructor, the move assignment operator isn't declared - so there isn't one. So you either have to provide one:

Foo& operator=(Foo&& other) {
    m_bar = std::move(other.m_bar);
    return *this;
}

Or, since all your members implement move operations themselves, you could just delete your move constructor and rely on the compiler-generated implicit move constructor and move assignment.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • Removal of the move constructor and/or the std::move() on Foo() does not seem to stop the compile error. – Edward J Brown Jul 15 '15 at 12:42
  • Definition of the move assignment operator with the addition of return *this. Does work. – Edward J Brown Jul 15 '15 at 12:45
  • @EdwardJBrown: [Works on gcc](http://coliru.stacked-crooked.com/a/34891faacd262655) – AndyG Jul 15 '15 at 12:46
  • @AndyG Doesn't seem to work in vs2013 msvc, just used your exact code and got the same error. Probably a Microsoft bug. Thanks anyway – Edward J Brown Jul 15 '15 at 12:51
  • @EdwardJBrown: Depending on your actual code (and not this toy problem), you may be implicitly deleting the move constructor/assignment by defining a copy constructor/assignment – AndyG Jul 15 '15 at 14:52
  • @AndyG http://pastebin.com/12qLJq3e Is the relevant code, removal of the assignment definition results in the error above when setting an array element = to an instance of OctreeNode. – Edward J Brown Jul 15 '15 at 15:19