Is there any advantage of using std::vector::emplace_back
and std::move
together? or it is just redundant since std::vector::emplace_back
will do an inplace-construction?
Cases for clarification:
std::vector<std::string> bar;
First:
bar.emplace_back(std::move(std::string("some_string")));
Second:
std::string str("some_string"); bar.emplace_back(std::move(str));
Third:
bar.emplace_back(std::move("some_string"));
emplace_back(std::move(w)); I recommend sticking with push_back for day-to-day use. You should definitely use emplace_back when you need its particular set of skills — for example, emplace_back is your only option when dealing with a deque<mutex> or other non-movable type — but push_back is the appropriate default.
Calling emplace_back will call the move constructor of std::string when std::move is used, which could save on a copy (so long as that string isn't stored in a SSO buffer). Note that this is essentially the same as push_back in this case.
std::move. std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.
With the simple benchmark here, we notice that emplace_back is 7.62% faster than push_back when we insert 1,000,000 object (MyClass) into an vector.
If T 's move constructor is not noexcept and is not CopyInsertable into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified. Since reallocation may take place, emplace_back requires the element type to be MoveInsertable for vectors.
I was under the assumption that emplace_back () implicitly uses/calls a move constructor Sorry, but you're assumption is wrong. emplace_back constructs the object in the vector in-place, i.e. instead of copying/moving the object from its parameters, it constructs the element directly which avoids the copy/move constructor.
emplace_back() vs push_back() When we use push_back(), we create an object and then insert it into the vector. With emplace_back(), the object is constructed in-place and saves an unnecessary copy. Please see emplace vs insert in C++ STL for details.
Then the temporary object will be destroyed. emplace_back () constructs a string in-place, so no temporary string will be created but rather emplace_back () will be called directly with char* argument. It will then create a string to be stored in the vector initialized with this char*.
In the second version, there is an advantage. Calling emplace_back
will call the move constructor of std::string
when std::move
is used, which could save on a copy (so long as that string isn't stored in a SSO buffer). Note that this is essentially the same as push_back
in this case.
std::move
in the first version is unnecessary, as the string is already a prvalue.
std::move
in the third version is irrelevant, as a string literal cannot be moved from.
The simplest and most efficient method is this:
bar.emplace_back("some_string");
That requires no unnecessary std::string
constructions as the literal is perfect-forwarded to the constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With