C/C++ Arena

Step 5 of 6

pair and tuple

Sometimes a function needs to return two things, like a minimum and a maximum, or a name and a score. You could make a struct, but for quick jobs the standard library has ready-made ones:

Structured bindings unpack either one into named variables in a single line.

#include <iostream>
#include <string>
#include <tuple>
#include <utility>

std::pair<int, int> div_mod(int a, int b) {
    return {a / b, a % b};          // braces build the pair
}

std::tuple<std::string, int, double> profile() {
    return {"ada", 36, 1.65};
}

int main() {
    auto [q, r] = div_mod(17, 5);
    std::cout << q << " remainder " << r << "\n";

    std::pair<std::string, int> item = {"shield", 1000};
    item.second -= 250;
    std::cout << item.first << " costs " << item.second << "\n";

    auto [name, age, height] = profile();
    std::cout << name << " " << age << " " << height << "\n";
    std::cout << std::get<1>(profile()) << "\n";
}
3 remainder 2
shield costs 750
ada 36 1.65
36

How it works

When to use a struct instead

.first and .second say nothing about what the values mean. If a pair travels far through your code, a small struct with real field names (name, score) is easier to read. Pairs and tuples are best for short-lived results that get unpacked right away.

Your task

Fill in the blanks.

Challenge 2

Read the fields of a std::tuple with std::get, using the index of each field. The program prints ropz 25.

Challenge 3

Write std::tuple<int, int, double> stats(const std::vector<int>& v) that returns the minimum, the maximum and the average of a non-empty vector, all at once. The caller unpacks it with auto [lo, hi, avg] = stats(v);.

Previous: unordered_map Next: Challenge: balanced brackets