0
0
CppHow-ToBeginner · 3 min read

How to Use std::unique in C++: Syntax and Examples

In C++, std::unique removes consecutive duplicate elements from a sorted or unsorted range by shifting unique elements to the front and returns an iterator to the new end. It does not resize the container, so you usually erase the redundant elements after calling it.
📐

Syntax

The basic syntax of std::unique is:

  • std::unique(ForwardIt first, ForwardIt last): Removes consecutive duplicates using operator==.
  • std::unique(ForwardIt first, ForwardIt last, BinaryPredicate p): Uses a custom predicate p to compare elements.

It returns an iterator to the new logical end of the range after duplicates are removed.

cpp
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last);

template<class ForwardIt, class BinaryPredicate>
ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p);
💻

Example

This example shows how std::unique removes consecutive duplicates from a vector of integers. The vector is then resized to remove the leftover duplicates.

cpp
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {1, 2, 2, 3, 3, 3, 4, 4, 5};

    // Remove consecutive duplicates
    auto last = std::unique(numbers.begin(), numbers.end());

    // Erase the redundant elements after unique
    numbers.erase(last, numbers.end());

    // Print the result
    for (int n : numbers) {
        std::cout << n << ' ';
    }
    std::cout << '\n';

    return 0;
}
Output
1 2 3 4 5
⚠️

Common Pitfalls

1. std::unique only removes consecutive duplicates. If duplicates are scattered, sort the container first.

2. std::unique does not change container size. You must erase the trailing elements manually.

3. Using std::unique without sorting may not remove all duplicates.

cpp
#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> v = {3, 1, 2, 3, 2, 1};

    // Wrong: unique without sorting
    auto last = std::unique(v.begin(), v.end());
    v.erase(last, v.end());

    for (int n : v) std::cout << n << ' ';
    std::cout << '\n';

    // Right: sort first
    std::vector<int> v2 = {3, 1, 2, 3, 2, 1};
    std::sort(v2.begin(), v2.end());
    last = std::unique(v2.begin(), v2.end());
    v2.erase(last, v2.end());

    for (int n : v2) std::cout << n << ' ';
    std::cout << '\n';

    return 0;
}
Output
3 1 2 3 2 1 1 2 3
📊

Quick Reference

Tips for using std::unique:

  • Use std::sort before std::unique to remove all duplicates.
  • Always erase the redundant elements after calling std::unique.
  • Use a custom predicate to define your own equality condition.
  • std::unique works on forward iterators like vectors, lists, and arrays.

Key Takeaways

std::unique removes only consecutive duplicates and returns the new end iterator.
Always erase elements after std::unique to resize the container properly.
Sort the container first if you want to remove all duplicates, not just consecutive ones.
You can provide a custom predicate to std::unique for custom duplicate definitions.