1. Vấn đề nó giải quyết
View mô tả phép biến đổi mà không tạo ngay một owning container mới chứa toàn bộ kết quả. Nó làm một giả định quan trọng trở nên rõ và có thể kiểm tra.
2. Kiến thức cần có
Range, lambda và cách duyệt bằng iterator.
Bạn cần biết biên dịch chương trình ngắn và đọc output.
3. Ý tưởng cốt lõi
View là công thức chứ chưa phải món ăn. Mỗi phần tử được yêu cầu mới kéo lượng công việc cần thiết qua công thức. Hãy đọc std::views như lời hứa chính xác; runtime precondition vẫn do lập trình viên chịu trách nhiệm.
4. Cú pháp tối thiểu
auto doubled = values | std::views::transform([](int x) { return x * 2; });5. Cách nó hoạt động
Chương trình đưa vào dạng nhỏ nhất cần thiết của
std::views.Nó áp dụng tính năng lên dữ liệu cố định và giữ owner cần thiết trong scope.
Nó in một kết quả để đối chiếu trực tiếp với source.
6. Lỗi thường gặp
View có thể mượn nguồn và giữ callable state, nên lifetime nguồn và captured reference vẫn quyết định tính đúng.
Hãy kiểm tra cả header, mức hỗ trợ thư viện C++20, lifetime và kiểu được suy luận.
7. Khi nào nên dùng
Nên dùng khi dữ liệu được filter hoặc transform theo nhu cầu và tránh intermediate container giúp rõ hoặc rẻ hơn.
Tránh dùng khi kết quả phải được sở hữu, truy cập lặp lại theo index hoặc giữ sau khi nguồn chết.
8. Ví dụ đơn giản
Transform view chỉ tăng counter khi iteration yêu cầu giá trị, qua đó cho thấy tính lazy trực tiếp. Tệp .cpp không nhận input nên kết quả dễ lặp lại.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp20/31_views_lazy_evaluation/main.cpp
// Day 31: Views and Lazy Evaluation
#include <iostream>
#include <ranges>
#include <vector>
int main() {
std::vector values{1, 2, 3};
int evaluations = 0;
auto doubled = values | std::views::transform([&](int value) {
++evaluations;
return value * 2;
});
std::cout << "before iteration = " << evaluations << '\n';
for (int value : doubled) {
std::cout << value << ' ';
}
std::cout << "\nafter iteration = " << evaluations << '\n';
}
9. Điều cần nhớ
std::viewsdiễn đạt ý tưởng C++20 trung tâm của ngày này.Ví dụ cô lập một hành vi bằng dữ liệu cố định.
Compiler check không thay thế suy luận về lifetime và runtime.
Ưu tiên interface nhỏ nhất nói đúng yêu cầu thật.
10. Câu hỏi tự kiểm tra
Dễ — Nhiệm vụ chính của
std::viewstrong ví dụ tối thiểu là gì?Trung bình — Vì sao transformation counter vẫn bằng 0 ngay sau khi tạo view?
Khó — Nếu lambda transform capture biến local bằng reference, object nào phải sống lâu hơn mọi lần duyệt view?