Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does moving an element from an STL container remove it from that container?

I have a Foobar class with a sayHello() method that outputs "Well hello there!". If I write the following code

vector<unique_ptr<Foobar>> fooList;
fooList.emplace_back(new Foobar());

unique_ptr<Foobar> myFoo = move(fooList[0]);
unique_ptr<Foobar> myFoo2 = move(fooList[0]);
myFoo->sayHello();
myFoo2->sayHello();

cout << "vector size: " << fooList.size() << endl;

The output is:

Well hello there!
Well hello there!
vector size: 1

I'm confused why this works. Shouldn't fooList[0] become null when I do the first move? Why does myFoo2 work?

Here's what Foobar looks like:

class Foobar
{
public:
    Foobar(void) {};
    virtual ~Foobar(void) {};

    void sayHello() const {
        cout << "Well hello there!" << endl; 
    };
};
like image 835
Bret Kuhns Avatar asked Dec 12 '22 06:12

Bret Kuhns


2 Answers

Shouldn't fooList[0] become null when I do the first move?

Yes.

Why does myFoo2 work?

It doesn't; it causes undefined behaviour. Your compiler happens to produce code that doesn't crash if you use a null pointer to call a non-virtual function that doesn't dereference this.

If you change the function as follows, it will be clearer what's happening:

void sayHello() const {
    cout << "Well hello there! My address is " << this << endl; 
}

Well hello there! My address is 0x1790010
Well hello there! My address is 0
vector size: 1
like image 150
Mike Seymour Avatar answered Mar 22 '23 22:03

Mike Seymour


The answer is: No, move operations doesn't remove elements from containers.

Another comment: the use of the emplace_back function is likely to be inadequate.

try:

vector<unique_ptr<Foobar>> fooList;
fooList.emplace_back( new Foobar );
like image 31
Fernando Pelliccioni Avatar answered Mar 23 '23 00:03

Fernando Pelliccioni