Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::vector::erase() doesn't want to move

Tags:

c++

c++11

move

I've got a std::vector<Foo> where Foo is a class containing Foo( Foo&& ) noexcept.

Adding objects to the container works flawlessly, however erasing them using std::vector::erase( iterator ) does not, GCC 4.7 tries to call the assignment operator which I have deleted. The exact error message is:

error: use of deleted function ‘Foobar& Foobar::operator=(const Foobar&)

Edit: Of course std::vector calls the assignment operator, not the copy constructor (you can see that in the error message, too). Fixed it in the description, sorry.

Here's example source code as requested:

#include <vector>

class Foo {
    public:
        Foo() {}
        Foo( Foo&& other ) noexcept {}

        Foo( const Foo& ) = delete;
        Foo& operator=( const Foo& ) = delete;
};

int main() {
    std::vector<Foo> v;

    v.push_back( Foo{} );
    v.erase( v.begin() );
}
like image 748
stschindler Avatar asked Sep 28 '12 09:09

stschindler


2 Answers

I couldn't reproduce it. Turns out good habits go a long way: I had the move asignment operator defined.

Live on GCC 4.7.2: http://liveworkspace.org/code/36c600c285f2c91649fd4f73784c2c00

#include <iostream>
#include <vector>

struct Foo
{
    Foo() {}

    Foo(Foo const&) = delete;
    Foo(Foo&&) throw() { }

    Foo& operator=(Foo const&) = delete;
    Foo& operator=(Foo&&) throw() { return *this; }
};

int main(int argc, char* args[])
{
    std::vector<Foo> v;
    v.emplace_back();
    v.emplace_back();
    v.emplace_back();
    v.emplace_back();

    auto it = v.begin();
    it++;
    v.erase(it);
}
like image 27
sehe Avatar answered Oct 28 '22 08:10

sehe


The problem is that you did not provide a move assignment operator. This is part of the vector Movable requirements for some functions.

like image 166
Puppy Avatar answered Oct 28 '22 06:10

Puppy