1. Vấn đề nó giải quyết
std::span truyền dãy phần tử liên tục mà không copy hay sở hữu, với kích thước nằm trong kiểu hoặc được giữ ở runtime. 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ó
Mảng liên tục, container và quy tắc lifetime không sở hữu.
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
Span là cửa sổ nhìn vào storage có sẵn. Static extent khắc kích thước vào type; dynamic extent mang kích thước cạnh pointer. Hãy đọc std::span 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
std::span<int, 3> fixed{data};
std::span<int> dynamic{data};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::span.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
Span không kéo dài lifetime của nguồn; tạo fixed-extent span từ số phần tử sai là không hợp lệ.
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 hàm cần view pointer-kèm-count an toàn trên array,
std::arrayhoặc vector.Tránh dùng khi callee phải sở hữu, resize hoặc giữ dữ liệu lâu hơn nguồn.
8. Ví dụ đơn giản
Fixed span và dynamic span nhìn cùng mảng ba phần tử và bộc lộ hằng extent khác nhau. 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/28_span_static_dynamic_extent/main.cpp
// Day 28: span, Static Extent, and Dynamic Extent
#include <array>
#include <iostream>
#include <span>
int main() {
std::array data{10, 20, 30};
std::span<int, 3> fixed{data};
std::span<int> dynamic{data};
fixed[1] = 99;
std::cout << "fixed extent = " << decltype(fixed)::extent << '\n';
std::cout << "dynamic extent marker = " << decltype(dynamic)::extent << '\n';
std::cout << "dynamic size = " << dynamic.size() << '\n';
std::cout << "data[1] = " << data[1] << '\n';
}
9. Điều cần nhớ
std::spandiễ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::spantrong ví dụ tối thiểu là gì?Trung bình — Extent nào nằm trong type, còn kích thước nào được lưu ở runtime?
Khó — Vì sao chuyển
std::span<int>sangstd::span<int, 3>có thể cần runtime precondition dù extent đích là compile-time?