@einpoklum ไม่ได้งานที่ดีงามของการแนะนำสิ่งที่spanเป็นคำตอบของเขาที่นี่ อย่างไรก็ตามแม้หลังจากอ่านคำตอบของเขาแล้วยังเป็นเรื่องง่ายสำหรับคนใหม่ที่ยังมีช่วงเวลาที่ยังคงมีคำถามแบบสตรีมที่คิดซึ่งยังไม่ได้รับคำตอบอย่างเต็มที่เช่น:
- เป็นวิธี
spanที่แตกต่างจากอาร์เรย์ C? ทำไมไม่ใช้เพียงหนึ่งในนั้น? ดูเหมือนว่ามันเป็นเพียงหนึ่งในบรรดาขนาดที่รู้จักกันดี ...
- เดี๋ยวก่อนมันฟัง
std::arrayแล้วจะspanแตกต่างอย่างไร?
- โอ้นั่นทำให้ฉันนึกไม่ออก
std::vectorเหมือนstd::arrayกันเหรอ?
- ผมงงไปหมดแล้ว. :( อะไรนะ
span?
ดังนั้นนี่คือความชัดเจนเพิ่มเติมเกี่ยวกับที่:
อ้างโดยตรงจากคำตอบของเขา - ด้วยส่วนเพิ่มเติมของฉันใน BOLD :
มันคืออะไร?
A span<T>คือ:
- นามธรรมที่มีน้ำหนักเบามากของลำดับของค่าที่ต่อเนื่องชนิด
Tหนึ่งในหน่วยความจำ
- โดยทั่วไปเดียว struct
{ T * ptr; std::size_t length; }กับพวงของวิธีการความสะดวกสบาย (โปรดสังเกตว่าสิ่งนี้แตกต่างอย่างชัดเจนstd::array<>เพราะspanช่วยให้สะดวกในการเข้าถึงวิธีเปรียบเทียบได้std::arrayผ่านตัวชี้ไปยังประเภทTและความยาว (จำนวนองค์ประกอบ) ของประเภทTในขณะที่std::arrayเป็นภาชนะจริงที่เก็บค่าประเภทหนึ่งค่าหรือมากกว่าT)
- ประเภทที่ไม่ได้เป็นเจ้าของ (เช่น"การอ้างอิงประเภท"แทนที่จะเป็น "ประเภทค่า"): มันไม่เคยจัดสรรหรือ deallocates อะไรและไม่ทำให้ตัวชี้สมาร์ทยังมีชีวิตอยู่
มันเคยเป็นที่รู้จักกันเป็นและแม้กระทั่งก่อนหน้านี้เป็นarray_viewarray_ref
ชิ้นส่วนที่หนาเหล่านี้มีความสำคัญต่อการทำความเข้าใจดังนั้นอย่าพลาดหรือเข้าใจผิด! A spanไม่ใช่ C-array ของ structs และไม่เป็น struct ของ C-array ชนิดTบวกความยาวของอาร์เรย์ (นี่จะเป็นสิ่งที่std::array ภาชนะบรรจุเป็นหลัก), NOR คือ C-array ของ structs ของตัวชี้ เพื่อพิมพ์Tบวกความยาว แต่แทนที่จะเป็นโครงสร้างเดียวที่มีตัวชี้Tเดียวให้พิมพ์และความยาวซึ่งเป็นจำนวนองค์ประกอบ (ชนิดT) ในบล็อกหน่วยความจำต่อเนื่องที่ตัวชี้พิมพ์Tชี้ไปที่! ด้วยวิธีนี้ค่าใช้จ่ายเพียงอย่างเดียวที่คุณเพิ่มโดยใช้spanเป็นตัวแปรในการจัดเก็บตัวชี้และระยะเวลาและความสะดวกสบายใด ๆ เข้าถึงฟังก์ชั่นที่คุณใช้ที่spanให้
นี่คือ UNLIKE a std::array<>เพราะstd::array<>จริง ๆ แล้วจัดสรรหน่วยความจำสำหรับบล็อกที่ต่อเนื่องกันทั้งหมดและ UNLIKE std::vector<>เพราะ a std::vectorนั้นเป็นเพียงแค่std::arrayว่ามันยังมีการเติบโตแบบไดนามิก (โดยปกติจะเพิ่มเป็นสองเท่าในแต่ละครั้ง) . A std::arrayได้รับการแก้ไขในขนาดและa spanไม่ได้จัดการหน่วยความจำของบล็อกมันชี้ไปที่มันเพียงชี้ไปที่บล็อกของหน่วยความจำรู้ระยะเวลาที่บล็อกของหน่วยความจำรู้ประเภทข้อมูลที่อยู่ใน C-array ในความทรงจำและให้ความสะดวกสบายเข้าถึงฟังก์ชั่นการทำงานที่มีองค์ประกอบในหน่วยความจำที่ต่อเนื่องกันว่า
มันเป็นส่วนหนึ่งของมาตรฐาน C ++:
std::spanเป็นส่วนหนึ่งของมาตรฐาน C ++ ณ C ++ 20 คุณสามารถอ่านเอกสารที่นี่: https://en.cppreference.com/w/cpp/container/span หากต้องการดูวิธีใช้ Google absl::Span<T>(array, length)ใน C ++ 11 หรือใหม่กว่าในวันนี้ดูด้านล่าง
คำอธิบายอย่างย่อและการอ้างอิงหลัก:
std::span<T, Extent>( Extent= "จำนวนองค์ประกอบในลำดับหรือstd::dynamic_extentถ้าเป็นไดนามิก" ระยะห่างเพียงชี้ไปที่หน่วยความจำและทำให้เข้าถึงได้ง่าย แต่ไม่ได้จัดการ!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>(สังเกตว่ามันมีขนาดคงที่N !):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T> (ขยายขนาดแบบไดนามิกโดยอัตโนมัติตามความจำเป็น):
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
ฉันจะใช้spanใน C ++ 11 หรือหลังจากนั้นในวันนี้ ?
Google ได้เปิดห้องสมุด C ++ 11 ภายในของพวกเขาในรูปแบบของห้องสมุด "Abseil" ไลบรารี่นี้มีวัตถุประสงค์เพื่อจัดเตรียม C ++ 14 ถึง C ++ 20 และเกินคุณสมบัติที่ทำงานใน C ++ 11 และใหม่กว่าเพื่อให้คุณสามารถใช้ฟีเจอร์ของวันพรุ่งนี้ได้ในวันนี้ พวกเขาพูดว่า:
ความเข้ากันได้กับมาตรฐาน C ++
Google ได้พัฒนาบทคัดย่อมากมายที่จับคู่หรือจับคู่คุณสมบัติที่รวมอยู่ใน C ++ 14, C ++ 17 และอื่น ๆ การใช้บทคัดย่อ Abseil ของ abstractions เหล่านี้ช่วยให้คุณสามารถเข้าถึงฟีเจอร์เหล่านี้ได้ในขณะนี้แม้ว่ารหัสของคุณจะยังไม่พร้อมสำหรับการใช้ชีวิตในโลกโพสต์ C ++ 11
นี่คือแหล่งข้อมูลและลิงค์สำคัญ ๆ :
- เว็บไซต์หลัก: https://abseil.io/
- https://abseil.io/docs/cpp/
- ที่เก็บ GitHub: https://github.com/abseil/abseil-cpp
span.habsl::Span<T>(array, length)คลาสส่วนหัวและเทมเพลต: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::spanถูกเสนอในปี 2560 ใช้กับ C ++ 17 หรือ C ++ 20 ยังเห็นP0122R5 ช่วง: มุมมองขอบเขตที่ปลอดภัยสำหรับลำดับของวัตถุ คุณต้องการกำหนดเป้าหมายภาษานั้นจริงๆหรือ จะเป็นปีก่อนคอมไพเลอร์จะทัน