ทำไม std :: min ถึงรองรับ initializer_list เท่านั้น

Sep 24 2020

เราสามารถใช้std::minวิธีด้านล่าง:

// 1.
int a = 1, b = 2;
std::min(a, b);

// 2.
std::min({1,2,3,4});

แต่ทำไมใช้ a std::vectorหรือไม่ได้std::listเพราะพารามิเตอร์ในเทมเพลตคือinitializer_list.

template <class T, class Compare>
  pair<T,T> minmax (initializer_list<T> il, Compare comp);

เหตุผลในการออกแบบนี้คืออะไร?

คำตอบ

3 LouisGo Sep 25 2020 at 02:39

หากต้องการอธิบายว่า "เหตุใดจึงไม่ยอมรับคอนเทนเนอร์" ให้คำนึงถึงความหมาย:

std::min({ "foo", "bar", "hello" })

ความหมายของstd::min()วิธีการ "ค้นหาค่าต่ำสุดในพารามิเตอร์อินพุต" ดังนั้นstd::min()/ std::max()ใช้สองอาร์กิวเมนต์หรือ initializer_list เป็น "อาร์กิวเมนต์เพิ่มเติม"

std::min() ไม่ได้ให้ความสามารถในการ "วนซ้ำผ่านคอนเทนเนอร์" เนื่องจากคอนเทนเนอร์ถือเป็น "พารามิเตอร์"

ในการหาค่าต่ำสุดในคอนเทนเนอร์มีstd::min_element()และคำแนะนำของ eerorika std::ranges::min()ใน C ++ 20 ควรจะดีกว่า

สำหรับstd::min_element()การใช้งานคุณอาจอ้างถึงฉันจะรับค่าสูงสุด (หรือต่ำสุด) ในเวกเตอร์ได้อย่างไร .

3 JaMiT Sep 25 2020 at 03:01

"ยิ่งพวกเขาคิดมากกับท่อประปามากเท่าไหร่การหยุดท่อระบายน้ำก็ง่ายขึ้นเท่านั้น" - ผู้บัญชาการ Montgomery Scott

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

กรณีหนึ่งที่ไม่ครอบคลุมคือการค้นหาองค์ประกอบขั้นต่ำมากกว่าสององค์ประกอบเมื่อองค์ประกอบเหล่านั้นไม่ใช่องค์ประกอบของคอนเทนเนอร์ (ช่วงภายใน a) กรณีนี้สามารถจัดการได้โดยการล่ามโซ่เดซี่std::minแต่มันค่อนข้างอึดอัดที่จะทำเช่นนั้น สำหรับ C ++ 11 มีการตัดสินใจว่าประโยชน์ของการจัดการพารามิเตอร์ที่มากขึ้นนั้นมีมากกว่าค่าใช้จ่ายในการทำให้เทมเพลตมีความซับซ้อนตราบใดที่ความซับซ้อนยังคงอยู่ให้น้อยที่สุด std::initializer_listดังนั้นเดียวกลไกง่ายๆสำหรับการจัดหาจำนวนข้อของการขัดแย้งได้รับการคัดเลือกคือ ไม่จำเป็นต้องอนุญาตตู้คอนเทนเนอร์โดยพลการเพราะstd::min_elementครอบคลุมสถานการณ์นั้นแล้ว

3 eerorika Sep 25 2020 at 02:27

แต่ทำไมไม่สามารถใช้ std :: vector หรือ std :: list ได้เนื่องจากพารามิเตอร์ในเทมเพลตคือ initializer_list

เนื่องจากไม่มีการโอเวอร์โหลดที่จะรับเวกเตอร์หรือรายการ สิ่งเหล่านี้ไม่ใช่รายชื่อผู้เริ่มต้น

เนื่องจาก C ++ 20 คุณสามารถใช้std::ranges::minซึ่งคุณสามารถส่งผ่านคอนเทนเนอร์เหล่านั้นหรือช่วงใดก็ได้ ก่อนหน้านั้นมีการstd::min_elementทำงานร่วมกับตัวทำซ้ำคู่ใด