# Comparing push_back() and emplace_back() in C++

Here's an improved version of your blog post:

---

## Understanding `emplace_back` in C++: A Simple Guide

When working with C++ vectors, adding new elements is a common task. Two popular methods for doing this are `push_back` and `emplace_back`. While they might seem similar at first glance, `emplace_back` has some unique advantages that make it a powerful tool in certain situations.

### What Makes `emplace_back` Special?

The `emplace_back` function is designed to add a new element directly to the end of a vector. What sets it apart is that it constructs the element in place, right in the vector's memory. This means there's no need to create a temporary object first, which can then be copied or moved into the vector. This can save both time and memory, especially when working with complex objects.

### A Real-World Example: String Hashing

Let's look at a practical example inspired by a common problem in competitive programming: finding duplicate strings in an array using string hashing.

```cpp
int compute_hasing(string const& s) {
    int n = s.size();
    int hash = 0;
    int p = 31;
    int power = 1;
    int mod = 1e9 + 9;
    for (int i = 0; i < n; i++) {
        hash = (hash + (s[i] - 'a' + 1) * power) % mod;
        power = (power * p) % mod;
    }
    return hash;
}

void findHashForEachString(vector<string> const& v) {
    vector<pair<int, int>> p;
    int n = v.size();
    for (int i = 0; i < n; i++) {
        p.push_back(make_pair(compute_hasing(v[i]), i));
    }
    sort(p.begin(), p.end());
    vector<vector<string>> groups;
    for (int i = 0; i < n; i++) {
        if (i == 0 || p[i].first != p[i - 1].first) {
            groups.emplace_back();
        }
        groups.back().push_back(v[p[i].second]);
    }
    for (const auto& group : groups) {
        for (const auto& str : group) {
            cout << str << " ";
        }
        cout << endl;
    }
}
```

### How `emplace_back` Is Used in This Code

In this function, `emplace_back()` is used to create a new empty vector whenever a new group of strings with the same hash is found. Here's how it works:

1. **Grouping Strings by Hash:** As we process each string, we compare its hash with the previous one. If the hash is different, we know we're dealing with a new group of strings.
    
2. **Creating a New Group:** `emplace_back()` is called to add a new empty vector to the `groups` vector. This new vector will hold all the strings in the current group.
    
3. **Adding Strings to the Group:** The current string is then added to this newly created vector.
    

This approach ensures that every time we encounter a new group of identical strings (based on their hashes), a new vector is created in `groups` to hold them.

### `emplace_back` vs. `push_back`: What's the Difference?

To really understand `emplace_back`, let's compare it with `push_back` using a simple example:

```cpp
struct Person {
    string name;
    int age;

    Person(string name, int age) : name(name), age(age) {
        cout << "Constructed Person: " << name << endl;
    }
};

int main() {
    vector<Person> people;

    Person john("John", 25);
    people.push_back(john);  // Creates a copy of 'john' and stores it in 'people'

    people.emplace_back("Doe", 30);  // Constructs 'Doe' directly in place

    return 0;
}
```

#### With `push_back`:

* You first create a `Person` object named `john`.
    
* When you call `push_back(john)`, a copy of `john` is made and added to the vector `people`.
    

#### With `emplace_back`:

* You pass the arguments `"Doe"` and `30` directly to `emplace_back()`.
    
* It constructs the `Person` object in place within the vector, without the need for a temporary object.
    

### Key Points

* `push_back`: Requires an existing object or temporary object to be moved or copied into the vector.
    
* `emplace_back`: Constructs the object directly in place using the provided arguments, which can save resources and avoid unnecessary copies.
