Modern C++ Utility Types

std::pair and std::tuple

There are occasions when two or three values go together but shouldn't be defined as a single class. The simple library types std::pair and std::tuple hold a fixed set of objects, which can each be of a different type.

A std::pair holds two values at a time. The values can be accessed by first and second, which are public members of the class.

#include <iostream>
#include <utility>

int main()
{
    // Group these two values into one pair
    std::pair<int, double> p{ 10, 3.14 };
    std::cout << p.first << ' ' << p.second << '\n';
}

p is a pair holding an int and a double. The constructor initializes first to 10 and second to 3.14. The print statement outputs the two members. Their being public means they can be read or written directly.

You may also use std::make_pair to create a pair, which will then be using type deduction.

#include <iostream>
#include <utility>

int main()
{
    // Let the initializer determine this variable type
    auto p{ std::make_pair(20, 2.71) };
    std::cout << p.first << ' ' << p.second << '\n';
}

Calls std::make_pair(20, 2.71) and creates a pair with first type of int and second type of double. The created object is assigned to p and the two values are printed. The keyword auto is used here to not write the long type name.

std::tuple extends to any fixed size. Values are extracted with std::get.

#include <iostream>
#include <tuple>

int main()
{
    // Store several differently typed values in one tuple
    std::tuple<int, double, char> t{ 5, 1.5, 'x' };
    std::cout << std::get<0>(t) << ' ' << std::get<1>(t) << ' ' << std::get<2>(t) << '\n';
}

Returns the ith element of the object t, where t is a tuple with three values of type int, double, and char. We get the first value with std::get<0>(t), the second with std::get<1>(t), and the third with std::get<2>(t). The three values are output in order, separated by spaces. The index used in std::get must be a compile time constant and cannot be given at runtime.

One can also use std::make_tuple to create a tuple.

#include <iostream>
#include <tuple>

int main()
{
    auto t{ std::make_tuple(7, 2.5, 'y') };
    std::cout << std::get<0>(t) << ' ' << std::get<1>(t) << ' ' << std::get<2>(t) << '\n';
}

The call to std::make_tuple is again deducing the three types and builds a tuple which is stored in t. Again, value access is with std::get and the values are printed out.

Both pair and tuple are value types. They are copyable, assignable, and comparable. When a function has to return two or three related values, returning a pair or a tuple is often cleaner than writing an ad hoc struct. The values stay together, the types stay explicit, and no additional class has to be written.

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.