C++ Tuple
Overview
The tuple is an immutable data structure that can store elements of different data types together. In this article, we will define and initialize tuples, along with various operations that can be performed on std::tuple.
Introduction to C++ Tuple
A tuple is a data structure capable of storing several values. They can be of different data types like int, char, etc. Tuples are immutable, and they have a fixed size.
Syntax of std::tuple
Syntax for creating a tuple:
For example, if we want to create a tuple that can hold 3 elements of the type integer, double, and character together, we can use the following statement:
Tuples can be initialized while declaring in the following way:
Here the tuple tp is initialized with values 4(integer), 0.6(double), and 'z'(character).
Why Do We Need std::tuple?
Common C++ data structures like vectors, arrays, priority queues, etc., can contain elements of a single data type. So when we need a data structure that can hold a fixed number of elements of different data types together, tuples are useful, as they may contain any data type, both primitive and abstract data types like string.
Common Operations on std::tuple
Getting Elements from a std::tuple
We can use get() to access tuple elements. This function takes the tuple name and index we want to accept as the arguments.
Output:
Explanation:
We may also use get() to modify tuple values. We access the elements of a particular index using get(), then we can directly modify its value. This is demonstrated with the below code:
Output:
Here we use get<1>(tp) to access the second element in the tuple, and we use the assignment operator to change its value to 0.1 from 0.6.
i) Getting the First Element from Tuple
As seen previously, we can use get() to access tuple elements in a particular index. We have zero-based indexing in C++ tuples. Hence the first element in a tuple is present at index 0. We can access that as follows:
Output:
Explanation: For the above-declared tuple, we use zero-based indexing to access the first element, so we have to get the element present at index 0. Hence we use get<0>(tuple_name) to access the first element.
ii) Getting Out Of Range Value from Tuple
Suppose we want to get an element with an index greater than what the size of the tuple permits. Then we are faced with a compilation error. For example, if a tuple has four elements, we can access elements with indexes 0, 1, 2, and 3. However, we cannot access an element with an index greater than or equal to 4 because the tuple has only four elements. This is demonstrated with the below code:
This code results in a compilation error as index four is out of range for tuple tp.
iii) Wrong Type Cast While Getting Value from Tuple
If we want to get an element from a tuple, using the wrong data type to access/store results in compilation errors. For example:
Explanation: In the above code, the element at index 1 is a string with the value "abcd". However, we are trying to cast it into a variable of the integer type, which results in a compilation error. Hence it is important to access and modify elements with proper data types when dealing with tuples.
iv) Getting Value from Tuple by Dynamic Index
For getting elements from the tuple using its index, we must always use compile-time constants for referring to the indexes. Else it results in a compilation error. This is explained using the below code:
This code results in a compilation error. This is because we are trying to use a dynamically assigned variable for the index. However, we may use C++ constant variables as unchangeable and read-only (not dynamically changed). For example:
The above line of code will result in no errors.
make_tuple()
This is used to assign the desired values to the declared tuple. For example, if our tuple can store int, float, char, and values i.e., we declare it like this:
Then we need to pass the desired values in the same order as the data types declared in the tuple. Hence, we can use the make_tuple() as follows:
Output:
Explanation: Here, we pass the arguments 5 (type: integer), 0.2 (type: float), and 'b'(type: character). They are passed in the same order as mentioned while declaring the tuple.
tuple_size()
For C++ tuples, tuple_size() returns the total number of elements in a tuple, i.e., the total size. As an argument, we pass the tuple to tuple_size(). For example:
Output:
In the above example, we created a tuple with 4 elements; hence tuple_size() returns 4, which is the size of the tuple.
swap()
This is used to swap all the elements of two tuples with each other. However, for swap() to work, the two tuples must contain elements of the same data type and in the same order. Example:
Output:
But if we use swap like in the below code:
This results in a compilation error, as for the swap to work, the two tuples should have the same data type in the same order. However, in the above example, tp1 and tp2 don't have elements of the same data type at index 1.
tie()
tie() enables a set of objects to act as a tuple. This is useful in unpacking tuple values into different variables.
Output:
We may want to prevent some values from getting unpacked. To do this, we use "ignore" instead of the particular variable as an argument to tie().
Output:
Since we pass ignore instead of a variable as an argument to tie() for the second value, we unpack only the first and third values.
tuple_cat()
tuple_cat() is used for concatenating two tuples into a single tuple. The new concatenated tuple is returned by tuple_cat(). The following code demonstrates its use:
Output:
Here we concatenated the two tuples tp1 and tp2; hence the concatenated tuple returned by tuple_cat() has elements of the two tuples combined while maintaining the order of the elements.
Working of Tuples in C++
Tuples can hold values of different data types together in a single object. We know that C++ pairs can also hold two values of different data types together. Hence tuples are a generalization of pairs. However, in C++, the tuple is not predefined; rather, we need to include it using the standard library <tuple>. The operations which we use on tuples, like get() for accessing values using the index and make_tuple() for assigning values to the tuple, are defined by the <tuple> library. The template class of std::tuple can be defined as:
Examples of C++ Tuple
We apply some of the previous operations learned below:
Output:
In the following example, we apply tie() and swap() operations:
Output:
Conclusion
- We have learned what tuples are and how they can store elements of different data types together.
- We went through the syntax for declaring a tuple in C++.
- We saw how to initialize the tuple with values while declaring the tuple directly.
- We saw how to assign values to tuples using make_tuple().
- We saw how we could get elements from tuples based on their indexes.
- We learned to avoid dynamic indexes and getting out of the range of tuples while trying to access tuple elements.
- We went through the importance and examples of different operations upon tuples such as: tuple_size(), swap(), tie(), and tuple_cat().
- We discussed the working and template class for tuples.