@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 spanlà 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
spankhá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, spankhác với nó như thế nào?
- Ồ, điều đó nhắc nhở tôi, không phải là
std::vectorgiống như std::arrayvậ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 spanphươ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::arraylà 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_viewvà 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 spanKHÔ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 Tcộ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 Tcộ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ụngspanlà 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à spancung 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::vectorlà về cơ bản chỉ là một std::arraymà 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::arraylà cố định về kích thước, và một spanthậ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::spanlà 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_extentnế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 spantrong 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.htiê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.