Pair in STL

What is a Pair in C++?

std::pair is a template class in the C++ Standard Template Library (STL) that represents a pair of values, where each value can have a different type.

It is defined in the <utility> header.

A std::pair is commonly used to store two elements as a single entity and is frequently employed in scenarios such as key-value associations, returning multiple values from a function, or simple grouping two related values together.

Syntax

#include <utility>

int main() {
    // Declaration and initialization of a pair
    std::pair<type1, type2> pairName; // Default initialization
    std::pair<type1, type2> pairName(value1, value2); // Initialization with values

    // Accessing elements of the pair
    pairName.first;  // Accesses the first element of the pair
    pairName.second; // Accesses the second element of the pair

    // Modification of elements
    pairName.first = newValue1;  // Modifies the first element of the pair
    pairName.second = newValue2; // Modifies the second element of the pair

    // Using std::make_pair to create a pair
    auto pairName = std::make_pair(value1, value2);

    return 0;
}

Example

#include <iostream>
#include <utility>

int main() {
    // Declaration and initialization of a pair
    std::pair<int, std::string> student(101, "John Doe");

    // Accessing elements of the pair
    std::cout << "Student ID: " << student.first << std::endl;
    std::cout << "Student Name: " << student.second << std::endl;

    // Modifying elements of the pair
    student.first = 102;
    student.second = "Jane Doe";

    // Using std::make_pair to create a pair
    auto subject = std::make_pair("Math", 95);

    return 0;
}

In this example, we declare a pair representing a student with an ID (integer), and a name (string). We then demonstrate how to access and modify the elements of the pair. Additionally, we use std::pair to create a pair with specified values.

Use Cases

1 Returning Multiple Values from Functions:

Pairs are useful when a function needs to return multiple values. Instead o fusing output parameters, a function can return a pair containing the desired values.

#include <iostream>
#include <utility>

std::pair<int, int> divide(int dividend, int divisor) {
    return std::make_pair(dividend / divisor, dividend % divisor);
}

int main() {
    int dividend = 10, divisor = 3;
    auto result = divide(dividend, divisor);

    std::cout << "Quotient: " << result.first << ", Remainder: " << result.second << std::endl;

    return 0;
}

Pair Inside Pair

#include <iostream>
#include <utility>

int main() {
    // Declaration and initialization of pairs
    std::pair<int, int> pair1(10, 20);
    std::pair<std::string, std::pair<int, int>> pair2("Nested Pair", std::make_pair(30, 40));

    // Accessing elements of the pairs
    std::cout << "Pair 1: (" << pair1.first << ", " << pair1.second << ")" << std::endl;
    std::cout << "Pair 2: (" << pair2.first << ", (" << pair2.second.first << ", " << pair2.second.second << "))" << std::endl;

    return 0;
}

// Output
Pair 1: (10, 20)
Pair 2: (Nested Pair, (30, 40))

Comparison Operators

The relational operators for std::pair, namely <, <=, >, >=, ==, != work based on lexicographical comparison of the pairs elements.

The < and <= operators compare two pairs lexicographically. They compare the elements of the pairs pairwise, starting from the first element. If the first elements are equal, the comparison continues with the second elements, and so on. The comparison stops as soon as a pair of elements is found where one is less than the corresponding element in the other pair, or until one pair is exhausted. If all elements are equal up to the point where one pair is exhausted, the shortest pair is considered “less".

Same is with other operators.

Example:

#include <iostream>
#include <utility>

int main() {
    // Define three pairs
    std::pair<int, int> pair1(10, 20);
    std::pair<int, int> pair2(10, 25);
    std::pair<int, int> pair3(10, 20);

    // Less Than (<) Operator
    std::cout << "pair1 < pair2: " << std::boolalpha << (pair1 < pair2) << std::endl; // true, because (10 < 15)
    std::cout << "pair1 < pair3: " << std::boolalpha << (pair1 < pair3) << std::endl; // false, because pairs are equal

    // Greater Than (>) Operator
    std::cout << "pair1 > pair2: " << std::boolalpha << (pair1 > pair2) << std::endl; // false, because (10 < 15)
    std::cout << "pair1 > pair3: " << std::boolalpha << (pair1 > pair3) << std::endl; // false, because pairs are equal

    // Equal To (==) Operator
    std::cout << "pair1 == pair3: " << std::boolalpha << (pair1 == pair3) << std::endl; // true, because pairs are equal

    // Not Equal To (!=) Operator
    std::cout << "pair1 != pair2: " << std::boolalpha << (pair1 != pair2) << std::endl; // true, because pairs are not equal

    return 0;
}

// Output
pair1 < pair2: true
pair1 < pair3: false
pair1 > pair2: false
pair1 > pair3: false
pair1 == pair3: true
pair1 != pair2: true

Functions

1 make_pair:

The make_pair function constructs a pair object with the specified values. It deduces the types of the pair elements automatically.

auto myPair = std::make_pair(10, "Hello");

2 first and second:

first and second are member variables of std::pair representing the first and second elements of the pair, respectively.

std::pair<int, std::string> myPair(10, "Hello");
int firstElement = myPair.first;       // Accessing the first element
std::string secondElement = myPair.second;  // Accessing the second element

3 swap:

The swap function swaps the contents of two pairs of the same type.

std::pair<int, int> pair1(1, 2);
std::pair<int, int> pair2(3, 4);
pair1.swap(pair2); // pair1 becomes (3, 4) and pair2 becomes (1, 2)