CodeNebula
C++20stladvanced

std::ranges::unique / unique_copy (C++20 Addition)

C++20 · The Big Four · Compiler flag: -std=c++20

Explanation

`unique` removes consecutive duplicates by moving them to the end and returning the new logical endpoint. `unique_copy` copies without consecutive duplicates to an output range.

Real-World Scenario

Deduplicate consecutive repeated sensor readings before storing them in a time-series database.

Quick Snippet

snippet.cpp
#include <ranges>
#include <algorithm>
#include <vector>

std::vector<int> data = {1, 1, 2, 3, 3, 3, 4};
auto [new_end, old_end] = std::ranges::unique(data);
data.erase(new_end, old_end);
// data == {1, 2, 3, 4}

Full Example

ranges_unique.cpp
// CodeNebula - C++20 Example: Ranges Unique
// Compile: g++ -std=c++20 -Wall -Wextra -o example ranges_unique.cpp

#include <algorithm>
#include <iostream>
#include <vector>
#include <string>

int main() {
    // ranges::unique - remove consecutive duplicates in place
    std::vector<int> nums = {1, 1, 2, 2, 2, 3, 3, 4, 5, 5};
    std::cout << "Original: ";
    for (int n : nums) std::cout << n << ' ';
    std::cout << '\n';

    auto [first, last] = std::ranges::unique(nums);
    nums.erase(first, last);
    std::cout << "After unique + erase: ";
    for (int n : nums) std::cout << n << ' ';
    std::cout << '\n';

    // unique with custom comparator (case-insensitive dedup)
    std::vector<std::string> words = {"Hello", "hello", "HELLO", "World", "world"};
    std::cout << "\nBefore: ";
    for (const auto& w : words) std::cout << w << ' ';
    std::cout << '\n';

    auto cmp = [](const std::string& a, const std::string& b) {
        return std::ranges::equal(a, b, [](char c1, char c2) {
            return std::tolower(c1) == std::tolower(c2);
        });
    };
    auto [f2, l2] = std::ranges::unique(words, cmp);
    words.erase(f2, l2);
    std::cout << "Case-insensitive unique: ";
    for (const auto& w : words) std::cout << w << ' ';
    std::cout << '\n';

    // ranges::unique_copy - copy without consecutive duplicates
    std::vector<int> src = {5, 5, 3, 3, 3, 7, 7, 1};
    std::vector<int> dst;

    std::ranges::unique_copy(src, std::back_inserter(dst));
    std::cout << "\nSource:      ";
    for (int s : src) std::cout << s << ' ';
    std::cout << '\n';
    std::cout << "Unique copy: ";
    for (int d : dst) std::cout << d << ' ';
    std::cout << '\n';

    // Sort first then unique to remove all duplicates
    std::vector<int> data = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
    std::ranges::sort(data);
    auto [ef, el] = std::ranges::unique(data);
    data.erase(ef, el);
    std::cout << "\nSorted unique: ";
    for (int d : data) std::cout << d << ' ';
    std::cout << '\n';

    return 0;
}
Run command
g++ -std=c++20 -Wall -Wextra -o example ranges_unique.cpp