std::expected trong C++23

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::variantstd::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ăngstd::optionalstd::variantstd::expected
Phân biệt rõ ràng thành công/lỗiKhôngKhông
Truy cập giá trị an toànKhôngKhô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ái
  • value() / error(): Truy cập giá trị/lỗi
  • value_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ểmNhược điểm
Ngoại lệTự động lan truyền lỗiChi phí hiệu năng cao, luồng điều khiển mờ ám
Mã lỗiHiệu năng caoDễ bị bỏ qua, thiếu an toàn kiểu dữ liệu
std::expectedRõ ràng, an toàn kiểu, hiệu năng tốtPhả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ư transformand_then giúp viết code rõ ràng và dễ bảo trì hơn.

Thẻ: C++23 std::expected Xử lý lỗi lập trình hệ thống

Đăng vào ngày 30 tháng 6 lúc 08:11