Professional C__ - Marc Gregoire [288]
cout << "d = " << d << endl;
get<1>(t2) *= 2;
cout << "d = " << d << endl;
// Outputs: d = 3.14
// d = 6.28
Code snippet from Tuple\tuple.cpp
The following block of code demonstrates something similar, but uses strings. It tries to change the value of the variable referenced by the third element of the tuple, which works perfectly because of the use of ref(), which results in a string&. However, trying to change the variable referenced by the fourth element will fail because that is a const string&:
cout << "str = " << str1 << endl;
get<2>(t2) = "Hello";
//get<3>(t2) = "Hello"; // ERROR: would be an error because of cref
cout << "str = " << str1 << endl;
// Outputs: str = Test
// str = Hello
Code snippet from Tuple\tuple.cpp
Tuples can also contain other containers. The following line creates a tuple where the first element is a string and the second element is a vector of integers:
tuple The standard defines a std::tie() utility function, which generates a tuple of references. The following example first creates a tuple consisting of an integer, a string, and a Boolean value. It then creates three variables: an integer, a string, and a Boolean and writes the values of those variables to the console. The tie(i, str, b) call will create a tuple containing a reference to i, a reference to str, and a reference to b. The assignment operator is used to assign tuple t1 to the result of tie(). Since the result of tie() is a tuple of references, the assignment actually changes the values in the three separate variables as is shown by the output of the values after the assignment: tuple int i = 0; string str; bool b = false; cout << "Before: i = " << i << ", str = \"" << str << "\", b = " << b << endl; tie(i, str, b) = t1; cout << "After: i = " << i << ", str = \"" << str << "\", b = " << b << endl; Code snippet from Tuple\tuple_tie.cpp The result is as follows: Before: i = 0, str = "", b = 0 After: i = 16, str = "Test", b = 1 You can use std::tuple_cat() to concatenate two tuples into one tuple. In the following example, the type of t3 will be tuple tuple tuple auto t3 = tuple_cat(t1, t2); Code snippet from Tuple\tuple_cat.cpp Tuples also support the following comparison operators: ==, <, !=, >, <= and >=. For the comparison operators to work, the element types stored in the tuple should support them as well. For example: tuple tuple if (t1 < t2) cout << "t1 < t2" << endl; else cout << "t1 >= t2" << endl; Code snippet from Tuple\tuple_comparison.cpp The output should be as follows: t1 >= t2 Iterating over the values of a tuple is unfortunately not straightforward. You cannot write a simple loop and call something like get(mytuple) because the value of i must be known at compile time. A solution is to use template metaprogramming, which is discussed in detail in Chapter 20, together with an example on how to print tuple values. SUMMARY Chapter 17 finishes the discussion of the C++ standard library and standard template library by showing you how to customize and extend the functionality provided by the STL. Chapter 17 Customizing and Extending the STL What allocators are What iterator adapters are How to extend the STL How to write your own
This chapter gave an overview of additional functionality provided by the C++ standard that did not fit in other chapters. You learned how to use std::function to create function pointers. This chapter also gave an overview of the new ratio template to define compile time rational numbers, the Chrono library, and the random number generation library. The chapter finished with a discussion on tuples, which are a generalization of pairs.
WHAT’S IN THIS CHAPTER?