mardi 30 décembre 2014

Using move to insert into a STL container

I am trying to better understand how move works when used in inserting an element into an STL container. I am looking at a code where an objected is allocated using new (created on the heap). Later on, when an insert is done, it seems the STL container allocates a new object and calls the move constructor. Is there a way to make the STL container directly use the object (take over the object (ptr) that was alloced).


I have the following sample code for some additional questions:



#include <iostream>
#include <vector>
using namespace std;

class foo
{
public:
uint32_t i[3];
string s1;

foo()
{ cout << "def ctor" << endl; }

foo(const foo& fm)
{ cout << "copy ctor" << endl; }

foo(const foo&& fm)
{ cout << "move ctor" << endl; }

foo& operator= (const foo& fm)
{ cout << "copy assign" << endl; return *this; }
};

vector<foo> vec_f;

int main()
{
foo f1;
cout << "---" << endl;
vec_f.push_back(f1);
cout << endl;

foo f2;
cout << "---" << endl;
vec_f.push_back(move(f2));
cout << endl;

foo *f3 = new (foo);
cout << "---" << endl;
vec_f.push_back(*f3);
cout << endl;

foo *f4 = new (foo);
cout << "---" << endl;
vec_f.push_back(move(*f4));
cout << endl;
}


Output as follow:



def ctor
---
copy ctor

def ctor
---
move ctor
copy ctor

def ctor
---
copy ctor
copy ctor
copy ctor

def ctor
---
move ctor


I am ignoring the calls to the default ctor for f1, f2, f3, f4 and focusing on the calls after "---".


f1 : foo is created using copy ctor. However, is this object created as a result of the STL code doing a new OR part of passing the object by value to a function (nothing to do with STL but a compiler thing)? I am guessing the latter. If so, where is the object creation when the element is inserted into the container?


f2 : foo is created using move ctor, by the STL code, right? And why/how is the copy ctor invoked right after? Is it because f2 is created on the stack (not heap)? If so, how does the STL code figure that out?


f3 : Most puzzling to me. Guessing the first copy ctor is invoked as part of passing a parameter by value (nothing to do with STL). How/why are the other two copy ctor called.


f4 : STL invoking the move ctor, so the move ctor can use the guts of the foo object. Is it possible to make the STL code just use the ptr (since it is created on heap). My understanding is objects in STL container are created on the heap anyways.


Sorry about the long post. Hopefully someone can shed some light.


Regards, Ahmed.


Aucun commentaire:

Enregistrer un commentaire