As stated in the question, can someone elaborate & help me understand the difference between emplace & insert member functions in vector or list.
How are they different from each other?
Thanks.
As stated in the question, can someone elaborate & help me understand the difference between emplace & insert member functions in vector or list.
How are they different from each other?
Thanks.
The difference is that insert() takes a reference to an already-constructed instance and copies it into the vector or list before the given position. emplace() constructs a new instance in place before the given position in the vector or list. You do not give it an instance to copy in, you give it arguments which will be passed to the constructor of the new instance. So in effect, emplace() grows the vector or list by enough to hold a new instance and then constructs the instance in the new empty spot.
Qt Code:
MyClass myClass( 42 ); // MyClass::MyClass( int value = 0 ) std::vector< MyClass > myClasses; myClasses.insert( myClasses.end(), myClass ); // makes a copy of myClass at the end of the vector myClasses.emplace( myClasses.end(), 43 ); // constructs a new MyClass instance at the end of the vector and initializes it with value 43 myClasses.emplace( myClasses.end() ); // uses the default MyClass constructor to create a new instance at the end of the vectorTo copy to clipboard, switch view to plain text mode
In both cases, insert() and emplace() return an iterator pointing to the new element.
Last edited by d_stranz; 28th October 2017 at 01:02.
<=== The Great Pumpkin says ===>
Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.
After reading the definition, I'm still unclear about the concept. This is what I grasped, correct me if I'm wrong.
"takes a reference to an already-constructed instance and copies it into ... " - does this mean, it consumes one element space in currently allocated storage ?
"emplace constructs a new instance" - does that mean, it keeps the "capacity" undisturbed, adds one element exclusively, irrespective of currently allocated storage ?
Here is what I tried -
Qt Code:
class MyClass { int d_val; public: MyClass(int i = 0) : d_val(i) {} int getVal() { return d_val; } }; int main() { MyClass m(99); vector<MyClass> v; v.insert(v.end(), 23); // "insert() takes a reference to an already-constructed instance" --- But I have passed a unconstructed element. v.emplace(v.end(), m); // "emplace() constructs a new instance in place" --- I have passed a already constructed element. for(auto i : v) cout << i.getVal() << endl; }To copy to clipboard, switch view to plain text mode
I'm still unable to comprehend the difference.
Thanks.
Last edited by rawfool; 28th October 2017 at 06:24.
In both cases, the vector or list will be grown if necessary to accommodate the new entry. size() will increase by 1, but capacity() may not if the underlying implementation's default allocation size is already big enough to hold the extra element or if you called reserve() with a larger value than the size() before the new element was added.
Ah, but here you are implicitly invoking the MyClass copy constructor because you are passing a MyClass instance as an argument:v.emplace(v.end(), m); // "emplace() constructs a new instance in place" --- I have passed a already constructed element.
Qt Code:
MyClass::MyClass( const MyClass & myClass )To copy to clipboard, switch view to plain text mode
so you end up with two instances, "m" - the one you constructed manually, and a copy of "m", built in place in the vector and initialized with the contents of "m". Even though your class doesn't explicitly define a copy constructor, C++ implements one for you (which by default makes a bitwise copy of the contents of the instance it is initialized with). Likewise for operator=().
To explain in another way:
insert() requires an already-existing instance of the class, which it then makes a copy of into the vector (using MyClass:: operator=( const MyClass & ))
emplace() does not require an existing instance, but creates one for you and initializes it with the extra arguments you pass in (using MyClass:: MyClass( arguments ))
<=== The Great Pumpkin says ===>
Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.
Ok, now I got it.
After reading your answer, I now tried with explicit constructor and it reported error for passing int value at insert. Now it makes sense to me.
Thanks a lot, d_stranzQt Code:
explicit MyClass(int i = 0) : d_val(i) {} ... ... v.insert(v.end(), 23); // compiler reports errorTo copy to clipboard, switch view to plain text mode
Yes, I missed your first example of insert( v.end(), 23 ). That would invoke the default constructor to create a temporary instance initialized to 23, which would then be copied into the vector.
Glad to help.
<=== The Great Pumpkin says ===>
Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.
Bookmarks