Giới thiệu tổng quan
std::expected là một lớp mẫu được giới thiệu trong C++23 nhằm biểu diễn các phép toán có thể thành công trả về giá trị hoặc thất bại trả về lỗi. Đây là giải pháp thay thế cho các phương pháp xử lý lỗi truyền thống như mã lỗi hoặc ngoại lệ, đồng thời kết hợp giữa an toàn kiểu dữ liệu và hiệu quả xử lý lỗi.
- Trạng thái thành công: Chứa giá trị kiểu
T - Trạng thái thất bại: Chứa thông tin lỗi kiểu
E
Thiết kế của std::expected lấy cảm hứng từ kiểu Either trong lập trình hàm, kết hợp các ưu điểm của std::variant và std::optional nhưng có ngữ nghĩa rõ ràng hơn cho trường hợp xử lý lỗi.
Tính năng chính
So sánh với các công cụ hiện tại
| Tính năng | std::optional | std::variant | std::expected |
|---|---|---|---|
| Phân biệt rõ ràng thành công/lỗi | Không | Không | ✓ |
| Truy cập giá trị an toàn | Không | Không | ✓ |
| Không có chi phí ngoại lệ | ✓ | ✓ | ✓ |
Các phương thức quan trọng
has_value(): Kiểm tra trạng tháivalue()/error(): Truy cập giá trị/lỗivalue_or(): Giá trị mặc định khi lỗi- Các thao tác chuỗi:
transform,and_then,or_else
Ví dụ minh họa
Hàm phân tích số
#include <expected>
#include <string>
std::expected<int, std::string> parseNumber(const std::string& input) {
try {
return std::stoi(input);
} catch (...) {
return std::unexpected("Định dạng số không hợp lệ");
}
}
Xử lý lỗi chuỗi
auto result = parseNumber("123");
if (result) {
std::cout << "Giá trị: " << *result << std::endl;
} else {
std::cout << "Lỗi: " << result.error() << std::endl;
}
Biến đổi giá trị thành công
auto result = computeValue(true)
.transform([](int x) { return x * 1.5f; });
Kết quả sẽ là std::expected<float, ErrorType>
Thao tác chuỗi với and_then
auto result = safeDivide(10, 2)
.and_then([](double x) { return safeDivide(x, 5); })
.and_then([](double x) { return safeDivide(x, 0); });
Các lưu ý quan trọng
- Phải kiểm tra trạng thái trước khi truy cập giá trị/lỗi
- Không được gọi
error()khi trạng thái là thành công - Loại lỗi nên là kiểu nhẹ như enum hoặc
std::error_code - Hiệu năng tối ưu khi sử dụng kiểu dữ liệu không cần cấp phát động
So sánh phương pháp xử lý lỗi
| Phương pháp | Ưu điểm | Nhược điểm |
|---|---|---|
| Ngoại lệ | Tự động lan truyền lỗi | Chi phí hiệu năng cao, luồng điều khiển mờ ám |
| Mã lỗi | Hiệu năng cao | Dễ bị bỏ qua, thiếu an toàn kiểu dữ liệu |
| std::expected | Rõ ràng, an toàn kiểu, hiệu năng tốt | Phải xử lý lỗi thủ công |
Kết luận
std::expected là công cụ mạnh mẽ cho xử lý lỗi trong C++23, đặc biệt phù hợp với các hệ thống yêu cầu hiệu năng cao và tính dự đoán. Việc kết hợp các thao tác chuỗi như transform và and_then giúp viết code rõ ràng và dễ bảo trì hơn.