Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any cases where it is incorrect to replace push_back with emplace_back?

Can I break a valid C++03 program by replacing std::vector::push_back with emplace_back and compiling it with C++ 11 compiler? From reading emplace_back reference I gather it shouldn't happen, but I'll admit I don't fully get rvalue references.

like image 802
Violet Giraffe Avatar asked Feb 27 '14 21:02

Violet Giraffe


People also ask

Should I use Push_back or Emplace_back?

Specific use case for emplace_back : If you need to create a temporary object which will then be pushed into a container, use emplace_back instead of push_back . It will create the object in-place within the container. Notes: push_back in the above case will create a temporary object and move it into the container.

Why Emplace_back back is faster than Push_back?

because emplace_back would construct the object immediately in the vector, while push_back , would first construct an anonymous object and then would copy it to the vector.

Should you always use Emplace_back?

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.

Is Push_back a copy?

Yes, std::vector<T>::push_back() creates a copy of the argument and stores it in the vector.


1 Answers

I constructed a short example that actually fails to compile when push_back is replaced by emplace_back:

#include <vector>
struct S {
    S(double) {}
  private:
    explicit S(int) {}
};
int main() {
    std::vector<S>().push_back(0); // OK
    std::vector<S>().emplace_back(0); // error!
}

The call to push_back needs to convert its argument 0 from type int to type S. Since this is an implicit conversion, the explicit constructor S::S(int) is not considered, and S::S(double) is called. On the other hand, emplace_back performs direct initialization, so both S::S(double) and S::S(int) are considered. The latter is a better match, but it's private, so the program is ill-formed.

like image 59
Brian Bi Avatar answered Nov 16 '22 00:11

Brian Bi