Question
I am confused about the difference between push_back and emplace_back in C++.
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
Since push_back has an overload that accepts an rvalue reference, I do not understand the purpose of emplace_back. When should emplace_back be used instead of push_back?
Short Answer
By the end of this page, you will understand that push_back adds an existing object to a container, while emplace_back constructs the object directly inside the container. You will also see when the difference matters, when it does not, and how to choose the clearer option in real C++ code.
Concept
push_back and emplace_back are both used to add elements to the end of containers such as std::vector.
The key idea is this:
push_backtakes an object that already exists and appends it to the container.emplace_backtakes constructor arguments and builds the object directly inside the container.
Why push_back exists
With push_back, you first have a value of the element type, and then the container stores it.
std::vector<std::string> names;
std::string s = "Alice";
names.push_back(s); // copies s
names.push_back(std::move(s)); // moves s
Here, push_back works with an already-created std::string.
Why emplace_back exists
With emplace_back, you can pass the arguments that would be used to construct the object.
Mental Model
Think of a container like an apartment building with empty rooms.
push_backmeans: bring in a finished piece of furniture and place it into the next room.emplace_backmeans: bring in the parts and assemble the furniture directly inside the room.
If the furniture is already built, push_back makes sense.
If you still have the parts needed to build it, emplace_back can avoid building it somewhere else first and then carrying it in.
That is the real difference: existing object vs in-place construction.
Syntax and Examples
Core syntax
vec.push_back(value); // value is already a Type object
vec.push_back(Type(args...)); // temporary Type object, then moved
vec.emplace_back(args...); // constructs Type directly in the container
Example 1: push_back with an existing object
#include <vector>
#include <string>
int main() {
std::vector<std::string> names;
std::string name = "Alice";
names.push_back(name); // copy
names.push_back(std::move(name)); // move
}
Explanation:
namealready existspush_back(name)copies it into the vectorpush_back(std::move(name))moves it into the vector
Example 2: emplace_back with constructor arguments
Step by Step Execution
Consider this example:
#include <vector>
#include <string>
#include <utility>
int main() {
std::vector<std::pair<int, std::string>> items;
items.emplace_back(1, "pen");
}
Step by step:
itemsis an empty vector ofstd::pair<int, std::string>.emplace_back(1, "pen")is called.- The arguments
1and"pen"are forwarded to the constructor ofstd::pair<int, std::string>. - The pair is constructed directly in the vector's storage.
- The vector now contains one element:
{1, "pen"}.
Now compare with this:
#include <vector>
#
{
std::vector<std::pair<, std::string>> items;
items.(std::<, std::string>(, ));
}
Real World Use Cases
Building container elements from multiple values
This is one of the best cases for emplace_back:
std::vector<std::pair<int, std::string>> products;
products.emplace_back(101, "Keyboard");
Useful when storing:
- pairs
- tuples
- structs or classes with several constructor arguments
Adding objects created elsewhere
If the object already exists, push_back is often the natural choice:
User user = loadUserFromDatabase();
users.push_back(std::move(user));
Parsing and collecting results
While reading a file or API response, you may build result objects directly in a container:
records.emplace_back(id, name, score);
This keeps code short and avoids explicit temporary objects.
Storing expensive-to-copy objects
For types that manage memory, file handles, or large buffers, constructing in place may avoid extra work.
Logging, metrics, and event collection
Applications often collect entries such as:
Real Codebase Usage
In real projects, developers usually choose based on intent, not just micro-optimization.
Common style guideline
- Use
push_back(x)whenxis already an object. - Use
emplace_back(args...)when you want to build the object in the container.
This makes code easier to read.
Example: parsing data into objects
struct Product {
int id;
std::string name;
double price;
Product(int id, std::string name, double price)
: id(id), name(std::move(name)), price(price) {}
};
std::vector<Product> products;
products.emplace_back(10, "Mouse", 19.99);
This pattern is common in:
- CSV parsing
- API response mapping
- database row conversion
Example: guard clauses before insertion
if (name.empty()) {
return;
}
products.emplace_back(id, name, price);
Common Mistakes
Mistake 1: thinking emplace_back is always faster
Not always.
If you already have an object, emplace_back may offer no real advantage:
std::string s = "Alice";
names.push_back(s);
names.emplace_back(s);
These can both copy from s.
Mistake 2: using emplace_back when push_back is clearer
Less clear:
std::string s = "Alice";
names.emplace_back(std::move(s));
Clearer:
std::string s = "Alice";
names.push_back(std::move(s));
If you already have a std::string, push_back expresses that directly.
Mistake 3: assuming no moves ever happen
Even with emplace_back, vector reallocation may move or copy existing elements when capacity grows.
Comparisons
| Feature | push_back | emplace_back |
|---|---|---|
| What it takes | An existing object of the element type | Constructor arguments for the element type |
| Main purpose | Add an object you already have | Construct object directly in the container |
| Can copy? | Yes | Yes, depending on arguments |
| Can move? | Yes | Yes, via perfect forwarding / constructor behavior |
| Avoids temporary object in some cases | Not usually | Yes |
| Best for | Existing values | New values built from parts |
| Readability | Often clearer when object already exists | Often concise when constructing on insert |
vs
Cheat Sheet
// If you already have an object:
vec.push_back(obj); // copy
vec.push_back(std::move(obj)); // move
// If you want to build the object in place:
vec.emplace_back(arg1, arg2, arg3);
Quick rules
push_backtakes aTobject.emplace_backtakes constructor arguments forT.emplace_backis usually a variadic template.emplace_backis most useful when constructing complex objects directly.- If an object already exists,
push_backis often clearer. emplace_backdoes not prevent vector reallocations.
Good examples
std::vector<std::string> v;
v.emplace_back("hello");
std::string s = "world";
v.push_back(s);
v.push_back(std::move(s));
Common pattern
FAQ
Is emplace_back always better than push_back?
No. It is better when you want to construct an element directly from constructor arguments. If you already have an object, push_back is often clearer.
Does push_back with an rvalue do the same thing as emplace_back?
Not exactly. push_back with an rvalue still receives a fully constructed object. emplace_back can build that object inside the container from constructor arguments.
Is emplace_back always faster?
No. It can avoid a temporary in some situations, but the difference may be tiny. Readability and correctness are usually more important.
Can emplace_back still copy or move objects?
Yes. It depends on the constructor and the arguments you pass. Also, container reallocation may move or copy existing elements.
Should I replace every push_back with emplace_back?
Usually no. Use push_back when you already have the object. Use emplace_back when constructing during insertion.
Why can work for a pair?
Mini Project
Description
Build a small C++ program that stores Book objects in a std::vector and compares inserting existing objects with constructing objects directly in the vector. This demonstrates the practical difference between push_back and emplace_back using a custom class.
Goal
Create and append Book objects using both push_back and emplace_back, and understand which one is appropriate in each case.
Requirements
- Create a
Bookclass with a title and page count. - Store multiple
Bookobjects in astd::vector<Book>. - Use
push_backwith an already-createdBookobject. - Use
emplace_backwith constructor arguments. - Print all stored books to verify the result.
Keep learning
Related questions
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Base Class Constructor Rules Explained
Learn how C++ base class constructors are called from derived classes, including order, syntax, defaults, and common mistakes.
C++ Casts Explained: C-Style Cast vs static_cast vs dynamic_cast
Learn the difference between C-style casts, static_cast, and dynamic_cast in C++ with clear examples, safety rules, and real usage tips.