Overview
STL containers such as vector, list, map to provide pushxxx and insert functions to add new elements.
Most of these functions endup creating a temporary object of the type T of the container.
In C++ 11, pushxxx and insert function variants that would accept a rvalue reference were added. Also a new emplacexxx functions were that would accept added to directly construct the object of type T in the container. Perfect forwarding is used to pass parameters for its constructor.
Details
In the following example, a vector of mystring is declared. Note that memory is preallocated for 10 elements by reserve call. This is to prevent side effects of vector copying when new nodes are added.
Appending new node
In the example below, lvalue and rvalue push_back and emplace_back functions are called to add a new element at the end of the vector.
vector<mystring> vs;mystring s("push_back(lvalue)"); vs.reserve(10); vs.push_back("dummy"); cout << endl << endl; cout << "push_back(lvalue)" << endl; vs.push_back(s); cout << endl << endl; cout << "push_back(rvalue)" << endl; vs.push_back("push_back(rvalue)"); cout << endl << endl; cout << "emplace_back()" << endl; vs.emplace_back("emplace_back()"); cout << endl << endl;
output
- The lvalue push_back function accepts a lvalue mystring object and calls lvalue copy constructor to add an element in the vector.
- The rvalue push_back function accepts a string literal. first it creates a temporary mystring object from the string literal and then calls move copy constructor to add an element in the vector.
- The emplace_back function that accepts a string literal calls memberwise constructor to add an element in the vector.
Therefore in case of emplace_back, parameters are perfect forwarded to the appropriate constructor of mystring , to add an element in the vector. also copy constructor never gets called. So the need for a temporary mystring object is avoided.
Inserting a new node
In the example below, lvalue and rvalue insert and emplace functions are called to insert a new element at the beginning of the vector.
vector<mystring> vs;mystring s("insert(lvalue)"); vs.reserve(10); vs.push_back("dummy"); cout << endl << endl; cout << "insert(lvalue)" << endl; vs.insert(vs.begin(),s); cout << endl << endl; cout << "insert(rvalue)" << endl; vs.insert(vs.begin(),"insert(rvalue)"); cout << endl << endl; cout << "emplace()" << endl; vs.emplace(vs.begin(), "emplace()"); cout << endl << endl;
output
In this scenario, there is no advantage of using emplace function if the vector is not empty as a temporary object is created nevertheless. This is highlighted in the red text above.
Summary of Examples
Name | Description | github | wandbox |
---|---|---|---|
Example | emplace_back | source output | source + output |
Example 2 | emplace | source output | source + output |
No comments:
Post a Comment