1. Vấn đề nó giải quyết
Nhiều bước có thể lỗi thường cần kiểm tra lặp và return sớm. Monadic operation C++23 nối chúng, giữ lỗi đầu tiên và bỏ các bước thành công phía sau.
2. Kiến thức cần có
Ngày 25: từ vựng monadic của
optional.Ngày 26: nhánh thành công và lỗi trong
expected.
3. Ý tưởng cốt lõi
Hãy hình dung bộ chuyển đường ray. and_then đi tiếp trên ray thành công, transform đổi giá trị mang theo, còn or_else xem hoặc thay ray lỗi. Hãy xác định giá trị đang được biến đổi rồi kiểm tra kiểu, lifetime hoặc quyền sở hữu kết quả. Bật C++23 chưa chắc thư viện đã triển khai đủ, vì vậy cần kiểm tra feature-test macro liên quan.
4. Cú pháp tối thiểu
read().and_then(parse).transform(normalize).or_else(report);5. Cách nó hoạt động
Ví dụ tạo biểu thức hoặc đối tượng nhỏ nhất cho Monadic operation và error pipeline với
std::expected.Chương trình nối hai bước số nguyên có thể lỗi khi thư viện hỗ trợ monadic
expected.Cuối cùng, nó in hoặc kiểm tra giá trị biến đổi cuối hoặc thông báo hỗ trợ thư viện trung thực để dễ đối chiếu.
6. Lỗi thường gặp
Kiểu lỗi không khớp làm pipeline không ghép được, và dùng
transformcho hàm đã trảexpectedtạoexpectedlồng không mong muốn.Không kiểm tra feature-test macro có thể chọn nhánh mã thư viện hiện tại chưa hỗ trợ.
7. Khi nào nên dùng
Nên dùng khi pipeline validation hoặc chuyển đổi tuyến tính có mô hình lỗi thống nhất.
Tránh dùng khi logic nghiệp vụ có phục hồi phân nhánh, rõ hơn khi viết câu lệnh tường minh.
8. Ví dụ đơn giản
Pipeline yêu cầu decode số, kiểm tra rồi đổi thành chuỗi hiển thị trong khi giữ thông báo lỗi đầu tiên. Chương trình dùng dữ liệu cố định để output dễ kiểm tra.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp23/27_expected_monadic_pipelines/main.cpp
#include <expected>
#include <iostream>
#include <string>
#include <version>
std::expected<int, std::string> begin_value() {
return 3;
}
std::expected<int, std::string> double_positive(int value) {
if (value <= 0)
return std::unexpected(std::string{"not positive"});
return value * 2;
}
int main() {
#if defined(__cpp_lib_expected) && __cpp_lib_expected >= 202211L
auto result = begin_value()
.and_then(double_positive)
.transform([](int value) { return value + 1; })
.or_else([](const std::string& error)
-> std::expected<int, std::string> {
return std::unexpected(error);
});
std::cout << *result << '\n';
#else
std::cout << "expected monadic operations unavailable\n";
#endif
}
9. Điều cần nhớ
Tách quy tắc chuẩn khỏi mức hỗ trợ thực tế.
Làm rõ lifetime, ownership và kiểu suy luận.
Ưu tiên cú pháp ngắn, đúng ý định.
Guard tính năng chưa được hỗ trợ đồng đều.
10. Câu hỏi tự kiểm tra
Dễ — Cú pháp ngắn nhất ở Phần 4 là gì và nhiệm vụ chính của nó là gì?
Trung bình — Đọc chương trình mẫu: giá trị, kiểu hoặc nhánh nào được quan sát, và vì sao?
Khó — Vì sao
transform(f)tạoexpected<expected<U, E>, E>khiftrảexpected<U, E>, và thao tác nào tránh mức lồng đó?