std::pair and std::tuple
Prerequisites
1. std::pair
std::pair is a simple container that holds exactly two values.
Useful for grouping two related values together.
- Return two values from a function
- Store simple key-value pairs
- Use in STL containers (e.g.,
map, priority_queue)
✔️ Declaration
1
2
3
| #include <utility>
std::pair<int, std::string> p;
|
✔️ Initialization
1
| std::pair<int, std::string> p = {1, "apple"};
|
Or:
1
| auto p = std::make_pair(1, "apple");
|
✔️ Access
1
2
| std::cout << p.first; // 1
std::cout << p.second; // apple
|
✔️ Comparison
1
2
3
4
5
6
7
| std::pair<int, int> a = {1, 2};
std::pair<int, int> b = {1, 3};
if (a < b)
{
// true (lexicographical comparison)
}
|
- Compare
.first - If equal → compare
.second
2. std::tuple
std::tuple is a container that can hold multiple values (more than two).
1
| std::tuple<T1, T2, T3, ...>
|
- Return multiple values from a function
- Temporary grouping of heterogeneous data
- Avoid creating a struct for simple cases
✔️ Declaration
1
2
3
| #include <tuple>
std::tuple<int, std::string, double> t;
|
✔️ Initialization
1
| auto t = std::make_tuple(1, "apple", 3.14);
|
✔️ Access
1
2
3
| std::cout << std::get<0>(t); // 1
std::cout << std::get<1>(t); // apple
std::cout << std::get<2>(t); // 3.14
|
✔️ Structured Binding (C++17)
1
2
3
| auto [id, name, value] = t;
std::cout << id << " " << name << " " << value;
|
Much cleaner and readable
✔️ Modify Value
✔️ Comparison
1
2
3
4
5
6
7
| std::tuple<int, int, int> a = {1, 2, 3};
std::tuple<int, int, int> b = {1, 2, 4};
if (a < b)
{
// true
}
|
Also lexicographical comparison
3. std::pair vs std::tuple
| Feature | pair | tuple |
|---|
| Number of elements | 2 | 2 or more |
| Access | .first, .second | std::get<N> |
| Readability | High | Lower (index-based) |
| Flexibility | Low | High |
1
2
3
4
5
| // pair
std::pair<int, int> p = {1, 2};
// tuple
std::tuple<int, int, int> t = {1, 2, 3};
|
4. Common Mistakes
❌ Forgetting index type
1
| std::get<i>(t); // ❌ wrong
|
✔️ Must be compile-time constant:
❌ Overusing tuple
If structure becomes complex:
1
| std::tuple<int, std::string, double, int, float>
|
Better to use:
1
2
3
4
5
6
| struct Data
{
int id;
std::string name;
double value;
};
|