CS253: Software Development with C++

Fall 2020

Pair And Tuple

Show Lecture.PairAndTuple as a slide show.

CS253 Pair And Tuple

pair

pair<string, double> teacher("Jack", 3.42);
cout << teacher.first << " makes $" << teacher.second << "/hour\n";
Jack makes $3.42/hour

pair definition

pair is not much more than this:

template<typename T1, typename T2>
struct pair {
    T1 first;
    T2 second;
};

except that comparison operators work.

pair comparison

vector<pair<string, string>> ff = {
    {"Storm", "Johnny"},
    {"Storm", "Sue"},
    {"Grimm", "Ben"},
    {"Richards", "Reed"},
};
sort(ff.begin(), ff.end());
for (auto &p : ff)
    cout << p.second << ' ' << p.first << '\n';
Ben Grimm
Reed Richards
Johnny Storm
Sue Storm

pair & multimap

multimap<string, string> ff = {
    {"Storm", "Johnny"},
    {"Storm", "Sue"},
    {"Grimm", "Ben"},
    {"Richards", "Reed"},
};
for (auto &p : ff)
    cout << p.second << ' ' << p.first << '\n';
Ben Grimm
Reed Richards
Johnny Storm
Sue Storm

tuple

tuple

using person = tuple<string, double, int, bool>;
person orange("DJT", 75, 239, false);
cout << boolalpha
     << "Name:    " << get<0>(orange)      << "\n"
     << "Height:  " << get<double>(orange) << "″\n"
     << "Weight:  " << get<2>(orange)      << "#\n"
     << "Popular: " << get<bool>(orange)   << "\n";
Name:    DJT
Height:  75″
Weight:  239#
Popular: false

Output

You can’t just << a pair or a tuple. What would go between the elements?

pair<int,int> p(1,2);
cout << p.first << '/' << p.second;
1/2
pair<int,int> p(3,4);
cout << p;
c.cc:2: error: no match for 'operator<<' in 'std::cout << p' (operand types are 
   'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::pair<int, int>')

get with pair

pair<string,float> p("π", 3.14159);
cout << p.first        << '\n'
     << get<string>(p) << '\n'
     << get<0>(p)      << '\n'
     << p.second       << '\n'
     << get<float>(p)  << '\n'
     << get<1>(p)      << '\n';
π
π
π
3.14159
3.14159
3.14159

Structured assignment

You can assign several variables at once (typically from a pair or tuple, also from a C array).

pair<string, float> p("pi", 3.14159);
auto [s, f] = p;
cout << s << ' ' << f << '\n';
pi 3.14159


tuple<double, int, char> t(1.2, 44, 'x');
auto [d, i, c] = t;
cout << d << ' ' << i << ' ' << c << '\n';
1.2 44 x


int a[] = {11,22};
const auto & [x, y] = a;
cout << x << ' ' << y << '\n';
11 22

Uses for structured assignment

map without structured assignment

map<int, string> numbers = {
    { 3, "three" },
    { 0, "zero" },
    { 2, "two" },
    { 1, "one" },
};

numbers[5] = "five";
numbers[4] = "four";
numbers[7] = "seven";
numbers[6] = "six";

for (auto p : numbers)
    cout << p.first << " is " << p.second << '\n';
0 is zero
1 is one
2 is two
3 is three
4 is four
5 is five
6 is six
7 is seven

Note that the map is sorted by the first element, the key.

map with structured assignment

map<int, string> numbers = {
    { 0, "zero" },
    { 1, "one" },
    { 2, "two" },
    { 3, "three" },
};

numbers[5] = "five";
numbers[4] = "four";
numbers[7] = "seven";
numbers[6] = "six";

for (auto [left,right] : numbers)
    cout << left << " is " << right << '\n';
0 is zero
1 is one
2 is two
3 is three
4 is four
5 is five
6 is six
7 is seven