@einpoklum làm một công việc tốt đẹp của việc giới thiệu những gì một span
là trong câu trả lời của mình ở đây . Tuy nhiên, ngay cả sau khi đọc câu trả lời của anh ấy, thật dễ dàng để một người mới bắt đầu vẫn có một chuỗi các câu hỏi suy nghĩ không được trả lời đầy đủ, chẳng hạn như sau:
- Làm thế nào
span
khác với một mảng C? Tại sao không chỉ sử dụng một trong những? Có vẻ như đó chỉ là một trong những người có kích thước được biết đến ...
- Đợi đã, nghe có vẻ như vậy
std::array
, span
khác với nó như thế nào?
- Ồ, điều đó nhắc nhở tôi, không phải là
std::vector
giống như std::array
vậy sao?
- Tôi thấy bối rối. :( Cái gì
span
?
Vì vậy, đây là một số rõ ràng bổ sung về điều đó:
NHỮNG CÂU HỎI TRỰC TIẾP CỦA TRẢ LỜI CỦA TÔI - VỚI CÁC THÊM CỦA TÔI TRONG BÓNG :
Nó là gì?
A span<T>
là:
- Một sự trừu tượng rất nhẹ của một chuỗi các giá trị liên tục
T
ở đâu đó trong bộ nhớ.
- Về cơ bản một cấu trúc duy nhất
{ T * ptr; std::size_t length; }
với một loạt các phương pháp thuận tiện. (Lưu ý rằng điều này khác biệt rõ rệt std::array<>
vì một span
phương thức truy cập tiện lợi, có thể so sánh với std::array
, thông qua một con trỏ để nhậpT
và độ dài (số phần tử) của loại T
, trong khi đó std::array
là một thùng chứa thực tế chứa một hoặc nhiều giá trị loại T
.)
- Loại không sở hữu (nghĩa là "loại tham chiếu" thay vì "loại giá trị"): Nó không bao giờ phân bổ cũng không giải quyết bất cứ điều gì và không giữ cho con trỏ thông minh tồn tại.
Nó trước đây được gọi là một array_view
và thậm chí sớm hơn như array_ref
.
Những phần táo bạo đó rất quan trọng đối với sự hiểu biết của một người, vì vậy đừng bỏ lỡ hoặc đọc sai chúng! A span
KHÔNG phải là một mảng C của các cấu trúc, cũng không phải là một cấu trúc của một mảng loại C T
cộng với chiều dài của mảng (về cơ bản nó sẽ là các std::array
thùng chứa ), NOR là một mảng C của các con trỏ để nhập T
cộng với độ dài, nhưng đúng hơn là một cấu trúc đơn có chứa một con trỏT
duy nhất để gõ và độ dài , là số phần tử (loại T
) trong khối bộ nhớ liền kề mà con trỏ cần nhập T
! Theo cách này, chi phí duy nhất bạn đã thêm bằng cách sử dụngspan
là các biến để lưu trữ con trỏ và độ dài và bất kỳ hàm truy cập tiện lợi nào bạn sử dụng mà span
cung cấp.
Đây là Không giống như một std::array<>
vì std::array<>
thực sự cấp phát bộ nhớ cho toàn bộ khối liền kề, và nó không giống như std::vector<>
bởi vì một std::vector
là về cơ bản chỉ là một std::array
mà cũng không năng động ngày càng tăng (thường là tăng gấp đôi kích thước) mỗi lần nó đầy lên và bạn cố gắng thêm cái gì khác với nó . Một std::array
là cố định về kích thước, và một span
thậm chí không quản lý bộ nhớ của khối nó trỏ đến, nó chỉ trỏ tới khối nhớ, biết bao lâu khối bộ nhớ là, hiểu biết những gì kiểu dữ liệu là một trong C-mảng trong bộ nhớ và cung cấp các hàm truy cập tiện lợi để làm việc với các phần tử trong bộ nhớ liền kề đó .
Nó là một phần của tiêu chuẩn C ++:
std::span
là một phần của tiêu chuẩn C ++ kể từ C ++ 20. Bạn có thể đọc tài liệu của nó ở đây: https://en.cppreference.com/w/cpp/container/span . Để xem cách sử dụng Google absl::Span<T>(array, length)
trong C ++ 11 trở lên ngay hôm nay , hãy xem bên dưới.
Tóm tắt Mô tả và Tài liệu tham khảo chính:
std::span<T, Extent>
( Extent
= "số phần tử trong chuỗi hoặc std::dynamic_extent
nếu động". Một khoảng chỉ trỏ vào bộ nhớ và giúp bạn dễ dàng truy cập, nhưng KHÔNG quản lý nó!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>
(chú ý rằng nó có kích thước cố địnhN
!):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T>
(tự động tăng kích thước khi cần thiết):
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
Làm thế nào tôi có thể sử dụng span
trong C ++ 11 trở lên ngày hôm nay ?
Google đã mở nguồn thư viện C ++ 11 nội bộ của họ dưới dạng thư viện "Abseil" của họ. Thư viện này nhằm cung cấp C ++ 14 đến C ++ 20 và hơn thế nữa là các tính năng hoạt động trong C ++ 11 trở lên, để bạn có thể sử dụng các tính năng của ngày mai, ngay hôm nay. Họ nói:
Khả năng tương thích với Tiêu chuẩn C ++
Google đã phát triển nhiều khái niệm trừu tượng phù hợp hoặc kết hợp chặt chẽ các tính năng được tích hợp vào C ++ 14, C ++ 17 và hơn thế nữa. Sử dụng các phiên bản Abseil của các bản tóm tắt này cho phép bạn truy cập các tính năng này ngay bây giờ, ngay cả khi mã của bạn chưa sẵn sàng cho cuộc sống trong một thế giới bài C ++ 11.
Dưới đây là một số tài nguyên và liên kết chính:
- Trang web chính: https://abseil.io/
- https://abseil.io/docs/cpp/
- Kho lưu trữ GitHub: https://github.com/abseil/abseil-cpp
span.h
tiêu đề và absl::Span<T>(array, length)
lớp mẫu: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::span
đã được đề xuất vào năm 2017. Nó áp dụng cho C ++ 17 hoặc C ++ 20. Đồng thời xem P0122R5, span: khung nhìn an toàn cho các chuỗi đối tượng . Bạn có thực sự muốn nhắm mục tiêu ngôn ngữ đó? Nó sẽ là nhiều năm trước khi trình biên dịch bắt kịp.