C++ std::list::unique

The std::list::unique function removes consecutive duplicate elements from a std::list. The list must already be sorted for this function to work as expected. Additionally, you can provide a custom binary predicate to define what constitutes a duplicate, allowing greater flexibility in filtering elements.


Syntax of std::list::unique

</>
Copy
// 1. Remove consecutive duplicates
void unique();

// 2. Remove consecutive duplicates using a custom predicate
template <class BinaryPredicate>
void unique(BinaryPredicate pred);

Parameters

ParameterDescription
predA binary predicate function that determines if two consecutive elements are considered equal. The predicate should return true for elements that should be removed.

Return Value

This function does not return a value. It modifies the list in place by removing consecutive duplicate elements.

Exceptions

The std::list::unique function does not throw exceptions unless the custom predicate throws an exception. It provides strong exception safety: if an exception is thrown, the list remains unchanged.


Examples for std::list::unique

Example 1: Removing Consecutive Duplicates

This example demonstrates how to use unique to remove consecutive duplicate elements from a sorted list:

Program

</>
Copy
#include <iostream>
#include <list>

int main() {
    std::list<int> myList = {10, 10, 20, 30, 30, 30, 40};

    std::cout << "List contents before unique: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Remove consecutive duplicates
    myList.unique();

    std::cout << "List contents after unique: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation:

  1. A std::list named myList is initialized with {10, 10, 20, 30, 30, 30, 40}.
  2. The unique function is called, removing consecutive duplicate elements (e.g., duplicate 10 and duplicate 30).
  3. The modified list contains only unique consecutive elements, and its contents are printed.

Output:

List contents before unique: 10 10 20 30 30 30 40
List contents after unique: 10 20 30 40

Example 2: Using a Custom Predicate

This example demonstrates how to use unique with a custom predicate to remove elements based on a specific condition:

Program

</>
Copy
#include <iostream>
#include <list>
#include <cmath>

// Custom predicate: Remove if two elements are approximately equal
bool isApproximatelyEqual(int a, int b) {
    return std::abs(a - b) <= 5;
}

int main() {
    std::list<int> myList = {10, 12, 15, 25, 30, 31, 40};

    std::cout << "List contents before unique: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Remove elements that are approximately equal
    myList.unique(isApproximatelyEqual);

    std::cout << "List contents after unique: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation:

  1. A std::list named myList is initialized with {10, 12, 15, 25, 30, 31, 40}.
  2. A custom predicate isApproximatelyEqual checks if two numbers differ by at most 5.
  3. The unique function is called with isApproximatelyEqual as the predicate, removing elements that satisfy this condition.
  4. The modified list contains only elements that are not approximately equal, and its contents are printed.

Output:

List contents before unique: 10 12 15 25 30 31 40
List contents after unique: 10 25 31 40

Example 3: Handling Floating-Point Numbers

This example demonstrates how unique can be used with floating-point numbers and a custom predicate to remove near-duplicates:

Program

</>
Copy
#include <iostream>
#include <list>

// Custom predicate: Check if two floating-point numbers are almost equal
bool isAlmostEqual(double a, double b) {
    return std::abs(a - b) < 0.01;
}

int main() {
    std::list<double> myList = {1.001, 1.002, 2.0, 2.005, 3.0};

    std::cout << "List contents before unique: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Remove near-duplicates
    myList.unique(isAlmostEqual);

    std::cout << "List contents after unique: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation:

  1. A std::list of floating-point numbers is initialized with {1.001, 1.002, 2.0, 2.005, 3.0}.
  2. A custom predicate isAlmostEqual checks if two numbers differ by less than 0.01.
  3. The unique function is called with the predicate, removing near-duplicates.
  4. The modified list contains only distinct floating-point values, and its contents are printed.

Output:

List contents before unique: 1.001 1.002 2 2.005 3
List contents after unique: 1.001 2 3