std :: dynarray vs std :: vector


84

C ++ 14 นำเสนอstd::dynarray:

std :: dynarray เป็นคอนเทนเนอร์ลำดับที่ห่อหุ้มอาร์เรย์ที่มีขนาดคงที่ที่โครงสร้างและไม่เปลี่ยนแปลงตลอดอายุการใช้งานของวัตถุ

std::dynarraystd::vectorจะต้องได้รับการจัดสรรในเวลาทำงานเหมือน

ดังนั้นประโยชน์และการใช้งานstd::dynarrayในขณะที่เราสามารถใช้แบบstd::vectorไหนที่มีไดนามิกมากกว่า (และปรับขนาดได้อีกด้วย)?


1
เดี๋ยวก่อน "C ++ 14" เป็นแท็กตั้งแต่เมื่อไหร่ ฉันมองหาวันนั้น แต่มันไม่มีอยู่ ...
Kerrek SB

1
จะถูกstd::valarrayเปลี่ยนชื่อเป็นstd::dynarray? อะไรที่เป็นพลวัตเกี่ยวกับstd::dynarrayเมื่อไม่สามารถปรับขนาดใหม่ได้?
yasouser

9
@yasouser valarrayไม่มีก็ไม่มีอะไรจะทำอย่างไรกับ เป็นแบบไดนามิกเนื่องจากความยาวของอาร์เรย์เป็นค่ารันไทม์จึงไม่จำเป็นต้องทราบเวลาคอมไพล์ซึ่งแตกต่างจากstd::array
Jonathan Wakely

21
โปรดทราบว่าในการประชุมคณะกรรมการมาตรฐาน C ++ เมื่อสัปดาห์ที่แล้วdynarrayได้ถูกลบออกจาก C ++ 14 และใส่ไว้ในข้อกำหนดทางเทคนิคในอนาคต (คิดว่าเป็น TR1 เวอร์ชันใหม่) เนื่องจากมีปัญหาทางเทคนิคที่ร้ายแรง
Pete Becker

2
dynarrayไม่ได้เป็นส่วนหนึ่งของร่าง C ++ 14 อีกต่อไป
Cassinaj

คำตอบ:


90

ดังนั้นประโยชน์และการใช้งานstd::dynarrayคืออะไรเมื่อเราสามารถใช้แบบstd::vectorไหนที่มีไดนามิกมากขึ้น (Re-sizable)?

dynarray มีขนาดเล็กและเรียบง่ายกว่า vectorเนื่องจากไม่จำเป็นต้องจัดการค่าขนาดและความจุแยกต่างหากและไม่จำเป็นต้องจัดเก็บตัวจัดสรร

อย่างไรก็ตามผลประโยชน์หลักของประสิทธิภาพนั้นมีจุดมุ่งหมายมาจากข้อเท็จจริงที่ว่าการใช้งานได้รับการสนับสนุนให้จัดสรรdynarrayบนสแตกเมื่อเป็นไปได้หลีกเลี่ยงการจัดสรรฮีปใด ๆ เช่น

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

การเพิ่มประสิทธิภาพนี้ต้องการความร่วมมือจากคอมไพเลอร์ไม่สามารถนำไปใช้เป็นประเภทไลบรารีบริสุทธิ์ได้และยังไม่มีการใช้เวทมนตร์คอมไพเลอร์ที่จำเป็นและไม่มีใครมั่นใจว่าจะทำได้ง่ายเพียงใด เนื่องจากขาดประสบการณ์ในการใช้งานในการประชุมคณะกรรมการ C ++ ในชิคาโกเมื่อสัปดาห์ที่แล้วจึงมีการตัดสินใจที่จะดึงstd::dynarrayจาก C ++ 14 และออกเอกสาร TS (ข้อกำหนดทางเทคนิค) ส่วนขยายอาร์เรย์แยกต่างหากการกำหนดstd::experimental::dynarrayและอาร์เรย์ของขอบเขตรันไทม์ (ARBs คล้ายกัน ถึง C99 VLAs) ซึ่งหมายความว่าstd::dynarrayแทบจะไม่อยู่ใน C ++ 14


1
ดีผมสงสัยว่าถ้ามีคนใด ๆการใช้งานที่ไม่น่ารำคาญของdynarrayในป่า ฉันคิดเสมอว่าคุณต้องใช้แนวทางปฏิบัติที่มีอยู่อย่างอิสระสองครั้งก่อนที่บางสิ่งจะมีสิทธิ์ได้รับมาตรฐาน
Kerrek SB

dynarrayไม่มีไม่มีการใช้งานที่เป็นที่รู้จักกันของกองจัดสรร แม้ว่าประสบการณ์การใช้งานจะมีประโยชน์มาก แต่ก็ไม่มีกฎที่กำหนดไว้ (แต่บางคนก็บอกว่าควรมี!)
Jonathan Wakely

เพียงแค่ระดมความคิดที่นี่ แต่สิ่งที่เกี่ยวกับการสร้าง 2 ฟังก์ชั่น: std :: dynarray make_dyn_autostorage (int) และ std :: dynarray make_dyn_heap (int)?
เสิร์ฟ Laurijssen

2
@KerrekSB ใช่ Library motion 10 ในชิคาโกคือ: "ย้ายเราสร้าง Working Paper สำหรับ Array Extensions TS ที่วางแผนไว้ลบการแก้ไขที่ใช้กับซีดี C ++ 14 โดยเอกสารสองฉบับN3639 " อาร์เรย์ขนาดรันไทม์โดยอัตโนมัติ ระยะเวลาการจัดเก็บ (แก้ไข 5) " N3662 ," C ++ Dynamic Arrays (dynarray) "และสั่งให้ตัวแก้ไขโปรเจ็กต์ Array Extensions TS ใช้คำเหล่านั้นกับ Array Extensions Working Paper เป็นเนื้อหาเริ่มต้น"
Jonathan Wakely

3
@ h9uest ที่ไม่มีส่วนเกี่ยวข้องกับ "พวก C ++" ซึ่งเป็นชื่อทางการสำหรับการส่งมอบของคณะกรรมการด้านเทคนิคISOดูที่iso.org/iso/home/standards_development/…และiso.org/iso/home/standards_development / …
Jonathan Wakely

31

อย่างที่คุณบอกว่าตัวเองstd::dynarrayมีไว้สำหรับไดนามิกอาร์เรย์ขนาดคงที่ ไม่สามารถปรับขนาดได้ เป็นการพูดประมาณว่าการปรับปรุงครั้งnew T[N]แล้วครั้งเล่าstd::unique_ptr<T[]>(new T[N])และมากกว่า

ไม่จำเป็นต้องปรับขนาดหรือจัดการความจุหมายความว่าคุณสามารถใช้โครงสร้างข้อมูลที่มีความซับซ้อนน้อยลงและใช้พื้นที่น้อยลง

ยิ่งไปกว่านั้น std::dynarrayเป็นสัตว์ประหลาดที่อนุญาตให้นำไปใช้งานในรูปแบบที่แตกต่างและไม่เฉพาะเจาะจงเช่นสามารถวางอาร์เรย์บนสแต็กได้ การเรียกใช้ฟังก์ชันการจัดสรรเป็น "ทางเลือก" คุณสามารถระบุผู้จัดสรรเพื่อสร้างองค์ประกอบของอาร์เรย์ได้ แต่นั่นไม่ใช่ส่วนหนึ่งของชนิด

คุณอาจสงสัยว่าทำไมเราถึงต้องการstd::dynarray และอาร์เรย์ที่มีความยาวผันแปรได้ VLAs ใน C ++ 14 มีข้อ จำกัด มากกว่ามาก สามารถเป็นตัวแปรเฉพาะที่เป็นตัวแปรอัตโนมัติและไม่มีวิธีระบุนโยบายการจัดสรรและแน่นอนว่าไม่มีอินเทอร์เฟซคอนเทนเนอร์มาตรฐาน


ตัวอย่างบางส่วนจาก 23.3.4.2 ของ "ร่างปัจจุบัน" (ใช้เวลานั้น Google cache):

explicit dynarray(size_type c);

เอฟเฟกต์:จัดสรรพื้นที่จัดเก็บสำหรับcองค์ประกอบ หรืออาจจะไม่ก่อให้เกิดโลกoperator new

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

ผลกระทบ:เทียบเท่ากับการก่อสร้างก่อนยกเว้นว่าแต่ละองค์ประกอบถูกสร้างด้วยการก่อสร้างใช้-จัดสรร

คุณสามารถใช้ตัวจัดสรรที่กำหนดเพื่อสร้างองค์ประกอบอาร์เรย์ได้หรือไม่นั้นเป็นลักษณะส่วนกลาง:

แม่แบบ struct uses_allocator, Alloc>: true_type {};

Allocข้อกำหนด:จะเป็นผู้จัดสรร (17.6.3.5) [ หมายเหตุ:ความเชี่ยวชาญของลักษณะนี้จะแจ้งให้ทราบส่วนประกอบของไลบรารีอื่น ๆ ที่dynarrayสามารถสร้างด้วยตัวจัดสรรแม้ว่าจะไม่มีลักษณะจัดสรรที่ซ้อนกันก็ตาม]

แก้ไข:คำตอบของ Jonathan Wakely นั้นน่าเชื่อถือและลึกซึ้งกว่ามาก


การส่งผ่านตัวจัดสรรไปยังตัวdynarrayสร้างของตัวสร้างจะไม่ถูกใช้เพื่อการจัดสรร แต่จะใช้เป็นอาร์กิวเมนต์ของตัวสร้างขององค์ประกอบเท่านั้น (โดยใช้ "การใช้ - การสร้างตัวจัดสรร") นั่นเป็นเหตุผลที่คุณไม่สามารถสอบถามได้ว่ามีการใช้ตัวจัดสรรหรือไม่: เพราะไม่เคยเป็น
Jonathan Wakely

@JonathanWakely: อ่าฉันเข้าใจผิด ขอบคุณแก้ไขแล้ว!
Kerrek SB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.