Bỏ qua để đến nội dung

std::pair và std::tuple

std::pairstd::tuple cho phép gộp nhiều giá trị (có thể khác kiểu dữ liệu) lại thành một đơn vị duy nhất, thường dùng khi cần trả về nhiều giá trị từ một hàm.

#include <utility> // std::pair
#include <iostream>
int main() {
std::pair<std::string, int> person = {"Alice", 25};
std::cout << person.first << std::endl; // Alice
std::cout << person.second << std::endl; // 25
return 0;
}

.first.second là hai thành viên cố định của pair, tương ứng với giá trị thứ nhất và thứ hai.

#include <utility>
#include <iostream>
int main() {
auto p = std::make_pair(10, 3.14); // Tự suy luận kiểu: pair<int, double>
std::cout << p.first << ", " << p.second << std::endl; // 10, 3.14
return 0;
}

Dùng pair để hàm trả về nhiều giá trị

Phần tiêu đề “Dùng pair để hàm trả về nhiều giá trị”
#include <utility>
#include <iostream>
std::pair<int, int> min_max(int a, int b, int c) {
int mn = std::min({a, b, c});
int mx = std::max({a, b, c});
return {mn, mx};
}
int main() {
auto result = min_max(5, 2, 9);
std::cout << "Min: " << result.first << ", Max: " << result.second << std::endl;
return 0;
}

Khi cần nhiều hơn hai giá trị, dùng std::tuple:

#include <tuple>
#include <iostream>
#include <string>
int main() {
std::tuple<std::string, int, double> student = {"Bob", 20, 3.8};
std::cout << std::get<0>(student) << std::endl; // Bob
std::cout << std::get<1>(student) << std::endl; // 20
std::cout << std::get<2>(student) << std::endl; // 3.8
return 0;
}

Truy cập phần tử của tuple qua std::get<chỉ_số>(tuple), khác với pair (dùng .first/.second).

Thay vì gọi std::get nhiều lần, có thể “giải nén” toàn bộ tuple vào các biến riêng cùng lúc:

#include <tuple>
#include <iostream>
#include <string>
std::tuple<std::string, int, double> get_student() {
return {"Charlie", 21, 3.5};
}
int main() {
std::string name;
int age;
double gpa;
std::tie(name, age, gpa) = get_student(); // Giải nén tuple vào 3 biến
std::cout << name << ", " << age << ", " << gpa << std::endl;
return 0;
}

Structured bindings (C++17) - cách hiện đại, gọn hơn

Phần tiêu đề “Structured bindings (C++17) - cách hiện đại, gọn hơn”
#include <tuple>
#include <iostream>
#include <string>
std::tuple<std::string, int, double> get_student() {
return {"Diana", 22, 3.9};
}
int main() {
auto [name, age, gpa] = get_student(); // Tự động khai báo và giải nén cùng lúc
std::cout << name << ", " << age << ", " << gpa << std::endl;
return 0;
}

Structured bindings cũng hoạt động tốt với pair:

std::pair<std::string, int> person = {"Eve", 30};
auto [name, age] = person;
std::cout << name << " la " << age << " tuoi" << std::endl;
  • Dùng pair khi chỉ cần gộp đúng 2 giá trị - cú pháp .first/.second rõ ràng, dễ đọc
  • Dùng tuple khi cần từ 3 giá trị trở lên
  • Nếu dữ liệu có ý nghĩa lâu dài trong chương trình (không chỉ dùng tạm thời), nên cân nhắc dùng struct thay vì pair/tuple để code dễ đọc hơn (tên thành viên rõ ràng thay vì .first, std::get<0>)
  • std::pair<T1, T2> gộp đúng 2 giá trị, truy cập bằng .first/.second
  • std::tuple<T1, T2, T3, ...> gộp nhiều giá trị hơn, truy cập bằng std::get<i>(tuple)
  • std::tie và structured bindings (auto [a, b, c] = ..., C++17) giúp giải nén tuple/pair gọn gàng
  • Cả hai thường dùng để một hàm trả về nhiều giá trị cùng lúc