- มีตัวอย่างมากมายของฟังก์ชั่นที่ฉันรู้ว่าจะไม่ทิ้ง แต่สำหรับคอมไพเลอร์ไม่สามารถกำหนดได้ด้วยตัวเอง ฉันควรผนวกการยกเว้นฟังก์ชันการประกาศฟังก์ชันในทุกกรณีดังกล่าวหรือไม่
noexcept
มันเป็นเรื่องยากเพราะมันเป็นส่วนหนึ่งของฟังก์ชั่นอินเตอร์เฟซ โดยเฉพาะอย่างยิ่งถ้าคุณกำลังเขียนไลบรารีรหัสลูกค้าของคุณอาจขึ้นอยู่กับnoexcept
คุณสมบัติ อาจเป็นการยากที่จะเปลี่ยนแปลงในภายหลังเนื่องจากคุณอาจผิดพลาดรหัสที่มีอยู่ อาจมีข้อกังวลน้อยกว่าเมื่อคุณใช้รหัสที่แอปพลิเคชันของคุณใช้
หากคุณมีฟังก์ชั่นที่ไม่สามารถโยนให้ถามตัวเองว่ามันจะชอบอยู่noexcept
หรือว่าจะ จำกัด การใช้งานในอนาคต? ตัวอย่างเช่นคุณอาจต้องการแนะนำการตรวจสอบข้อผิดพลาดของข้อโต้แย้งที่ผิดกฎหมายโดยการโยนข้อยกเว้น (เช่นสำหรับการทดสอบหน่วย) หรือคุณอาจขึ้นอยู่กับรหัสห้องสมุดอื่น ๆ ที่อาจเปลี่ยนแปลงข้อกำหนดข้อยกเว้น noexcept
ในกรณีที่จะปลอดภัยที่จะอนุรักษ์และงด
noexcept
ในทางตรงกันข้ามถ้าคุณมีความมั่นใจว่าฟังก์ชั่นไม่ควรโยนและมันเป็นเรื่องที่ถูกต้องว่ามันเป็นส่วนหนึ่งของข้อกำหนดที่คุณควรประกาศ อย่างไรก็ตามโปรดทราบว่าคอมไพเลอร์จะไม่สามารถตรวจพบการละเมิดnoexcept
หากการใช้งานของคุณเปลี่ยนแปลง
- สำหรับสถานการณ์ใดที่ฉันควรระวังเกี่ยวกับการใช้ noexcept มากขึ้นและสำหรับสถานการณ์ใดที่ฉันสามารถหลีกเลี่ยง noexcept โดยนัย (false) ได้
มีฟังก์ชั่นสี่ประเภทที่คุณควรมีสมาธิเพราะมันอาจจะมีผลกระทบมากที่สุด:
- การดำเนินการย้าย (ตัวดำเนินการกำหนดค่าย้ายและตัวสร้างการย้าย)
- การดำเนินการแลกเปลี่ยน
- deallocators หน่วยความจำ (ตัวดำเนินการลบตัวดำเนินการลบ [])
- destructors (แม้ว่าสิ่งเหล่านี้จะเกิดขึ้นโดยปริยาย
noexcept(true)
เว้นแต่คุณจะสร้างมันขึ้นมาnoexcept(false)
)
โดยทั่วไปแล้วฟังก์ชั่นเหล่านี้น่าจะเป็นไปได้noexcept
และเป็นไปได้มากว่าการใช้งานไลบรารีสามารถใช้ประโยชน์จากnoexcept
คุณสมบัติได้ ตัวอย่างเช่นstd::vector
สามารถใช้การดำเนินการย้ายที่ไม่ใช่การขว้างปาได้โดยไม่ต้องเสียสละข้อยกเว้นที่แข็งแกร่ง มิฉะนั้นจะต้องถอยกลับไปที่การคัดลอกองค์ประกอบ (เช่นเดียวกับใน C ++ 98)
การเพิ่มประสิทธิภาพชนิดนี้อยู่ในระดับอัลกอริทึมและไม่พึ่งพาการปรับให้เหมาะสมของคอมไพเลอร์ มันอาจมีผลกระทบที่สำคัญโดยเฉพาะอย่างยิ่งหากองค์ประกอบมีราคาแพงในการคัดลอก
- เมื่อใดที่ฉันจะคาดหวังว่าจะสังเกตเห็นการปรับปรุงประสิทธิภาพตามจริงหลังจากใช้งาน noexcept โดยเฉพาะอย่างยิ่งให้ตัวอย่างของรหัสที่คอมไพเลอร์ C ++ สามารถสร้างรหัสเครื่องที่ดีขึ้นหลังจากการเพิ่ม noexcept
ข้อได้เปรียบของการnoexcept
ต่อต้านข้อกำหนดที่ไม่มีข้อยกเว้นหรือthrow()
เป็นมาตรฐานที่ช่วยให้คอมไพเลอร์มีอิสระมากขึ้นเมื่อมันมาถึงกองคลี่คลาย แม้แต่ในthrow()
กรณีคอมไพเลอร์ก็ต้องคลายสแต็คอย่างสมบูรณ์ (และต้องทำในลำดับย้อนกลับที่แน่นอนของการสร้างวัตถุ)
ในnoexcept
กรณีตรงกันข้ามมันไม่จำเป็นต้องทำเช่นนั้น ไม่มีความต้องการที่สแต็กจะต้องคลาย (แต่คอมไพเลอร์ยังคงได้รับอนุญาตให้ทำ) อิสระดังกล่าวอนุญาตให้ใช้การปรับโค้ดให้เหมาะสมยิ่งขึ้นเนื่องจากจะช่วยลดค่าใช้จ่ายในการลดสแต็ก
คำถามที่เกี่ยวข้องเกี่ยวกับการยกเว้นสแต็กคลี่คลายและประสิทธิภาพการทำงานเข้าไปในรายละเอียดเพิ่มเติมเกี่ยวกับค่าใช้จ่ายเมื่อจำเป็นต้องคลี่คลายสแต็ค
ฉันยังแนะนำหนังสือ Scott Meyers "Effective Modern C ++", "รายการที่ 14: ประกาศฟังก์ชั่นไม่มีข้อยกเว้นหากพวกเขาจะไม่ส่งข้อยกเว้น" สำหรับการอ่านเพิ่มเติม
move_if_nothrow
(หรือ whatchamacallit) จะเห็นการปรับปรุงประสิทธิภาพหากไม่มี ctor ย้ายแบบไม่ยกเว้น